[ Миронченко ] Императивное и объектно-ориентированное програмирование на Turbo Pascal и Delphi
.pdf
51
не печатайте на экране одни цифры. Босс должен увидеть хороший отчет, а не то он может разозлиться на вас и даже выгнать с работы…
3.По введенным двум катетам вычислите гипотенузу, площадь и периметр прямоугольного треугольника, и выведите их на экран.
4.По введенному радиусу программа должна выводить на экран длину окружности, площадь круга, объем шара.
Длина окружности |
Площадь круга |
Объем шара |
||
L = 2πR |
S = π R2 |
V = |
4 |
πR 3 |
|
|
|
||
|
|
3 |
|
|
Во всех формулах R – радиус, а число π - это иррациональное число, и оно ≈ 3,1415
Значение числа π можно получить с помощью встроенной функции Pi.
Например, чтобы в переменную L записать длину окружности радиуса R, то можно записать так:
L:=2*Pi*R;
5.Вам заданы радиус основания цилиндрической железной бочки, ее высота и толщина (все в метрах). Вы должны вычислить, какой объем бочки, и какова масса пустой бочки (в кг). Плотность железа – 7800 кг .
м3
Объем цилиндра вычисляется по формуле V = π R2 H , где R – радиус цилиндра, H – его высота.
6.Начертите график функции y = {x}.
•Функция y = f (x) называется периодической, если существует такое число T > 0 , что для любого x из области определения функции f (x) выполняется условие
f(x + T ) = f (x) .
•Минимальное из чисел Т называется периодом функции y = f (x) .
7.Докажите, что функция y = {x} – периодическая, и ее период =1.
8.Верно ли, что {−x} = 1−{x} . Объясните.
9.Докажите неравенство {x + y} ≤ {x} + {y}.
10.Исходя из результата предыдущей задачи, докажите, что [x + y] ≥ [x] + [ y] .
•Функция y = f (x) называется аддитивной, если f (x + t) = f (x) + f (t) .
11.Обобщите результаты задач 4,5, доказав следующее утверждение:
Если аддитивная функция |
f (x) |
представима в виде f (x) = f1 (x) + f 2 (x) , то из того, |
||||||
что f1 (x + y) ≤ f1 (x) + f1 ( y) следует f 2 (x + y) ≥ f 2 (x) + f 2 ( y) , и наоборот. |
||||||||
12.Пусть d (x) - расстояние между числом x |
и ближайшим целым числом. Для любого |
|||||||
|
6n−1 |
|
|
m |
|
m |
||
|
|
|||||||
натурального n вычислите: Fn |
= ∑ min d |
|
|
, d |
|
|
. |
|
|
|
|||||||
|
m=1 |
|
|
6n |
|
3n |
||
52
Глава 3: Использование оператора if
3.1.Немного справочной информации
Вначале предыдущей главы мы ввели понятия алфавита, идентификатора, переменной, константы. Сейчас мы рассмотрим, как эти понятия реализованы в ТР.
Алфавит
Алфавит языка Турбо Паскаль включает буквы, цифры, специальные символы, пробелы.
Буквы — это буквы латинского алфавита от а до z и от А до Z, а также знак подчеркивания _.
Специальные символы Турбо Паскаля:
+ - * / = , ' . : ; < > [ ] ( ) { } ^ @ $ #
Из специальных символов состоят также некоторые пары символов, которые обладают собственным смыслом:
<> <= >= := (* *) (. .)
Цифры — десятичные цифры от 0 до 9.
Пробелы в ТР используются в качестве разграничителей.
То, что алфавит включает в себя лишь указанные выше символы, не означает, что вы можете использовать в программном коде только их. Вы знаете, что в строковых константах можно использовать и кириллицу. Однако строковые константы не являются частью языка – это просто данные, которыми оперирует программа.
Идентификаторы в ТР могут состоять из букв или цифр, причем первым символом должна обязательно быть буква.
В ТР между строчными и заглавными буквами различий нет, поэтому, например, следующие идентификаторы будут считаться одинаковыми:
Herz herz
F2e3 f2E3
Некоторые слова, которые называются зарезервированными, используются в языке для обозначения операторов, объявлений и т.д. Они не могут использоваться в качестве идентификаторов.
В таблице приведен их полный список.
and |
end |
nil |
shr |
asm |
file |
not |
string |
array |
for |
object |
then |
begin |
function |
of |
to |
case |
goto |
or |
type |
const |
if |
packed |
unit |
constructor |
implementation |
procedure |
until |
destructor |
in |
program |
uses |
div |
inline |
record |
var |
do |
interface |
repeat |
while |
downto |
label |
set |
with |
else |
mod |
shl |
xor |
53
Для того, чтобы задать специальные свойства подпрограммам, используются стандартные директивы. Ниже приведен список стандартных директив:
absolute |
far |
near |
assembler |
forward |
private |
external |
interrupt |
virtual |
По умолчанию зарезервированные слова и стандартные директивы в окне редактора ТР выделяются белым цветом (но в ТР можно менять цвета фона и символов, поэтому вполне возможно, что в вашем ТР кто-то уже полазил в настройках, и цвета у вас на экране другие).
Константы
В качестве числовых констант можно использовать и шестнадцатеричные числа. Шестнадцатеричное число состоит из шестнадцатеричных цифр, которым предшествует знак доллара $. Диапазон шестнадцатеричных чисел — от $00000000 до
$FFFFFFFF.
Символьная константа — это любой символ, заключенный в апострофы: ' z' - символ z;
Если надо записать сам символ апострофа, он удваивается: ‘’’’ .
Строковая константа — любая последовательность символов (кроме символа возврата каретки), заключенная в апострофы. Если в строке нужно написать апостроф, - он удваивается, например: 'Helga''s Buch'.
|
3.2. Структура программы в Turbo Pascal |
Структура программы в ТР имеет следующий вид: |
|
program |
{Имя программы} |
uses |
{Список используемых модулей} |
label |
{Описание меток} |
const |
{Описание констант} |
type |
{Описание типов} |
var |
{Описание переменных} |
procedure |
{Блок описания процедур } |
function |
{ Блок описания функций} |
exports |
{Описания экспортируемых имен} |
|
{Раздел операторов (Наша основная программа)} |
begin {начало исполняемой части} {Операторы}
end.
Пока что не будем объяснять значения неизвестных для вас разделов, но заметим, что желательно описывать блоки программы именно в такой последовательности (хотя некоторые из них можно менять местами).
54
3.3.Числовые типы данных
Впрограммах, написанных в предыдущей главе, мы использовали лишь 2 типа данных: Integer и Real. Но числовых типов в ТР в 5 раз больше: 5 целых типов и 5 вещественных. В таблицах приведены описания всех этих типов.
Целые типы
Идентификатор |
Диапазон представления чисел |
Требуемый размер памяти |
|
|
( в байтах) |
Shortint |
− 27..27 − 1 |
1 |
Integer |
− 215..215 − 1 |
2 |
Longint |
− 231..231 − 1 |
4 |
Byte |
0..28 − 1 |
1 |
Word |
0..216 − 1 |
2 |
Размеры диапазонов прямо следуют из способа хранения целых чисел. Например, тип ShortInt – целый тип, принимающий как положительные, так и отрицательные значения, а значит, его двоичное представление записывается в двоичном дополнительном коде (см. п. 1.6.). Следовательно, минимальное отрицательное число записывается в виде: 1000 0000, или -128. А максимальное число, - в виде 0111 1111, или 127. Аналогичные рассуждения можно провести и для любого другого целого типа данных.
Вещественные типы
Давайте разберемся с представлением вещественного числа. Вы уже знаете, что действительное число печатается в виде ±mEp . Например, 39.456, будет напечатано
так: 3.9456000000Е+01 (т.е. 3.9456 101 ). Число m называется мантиссой числа, p – показатель степени. Такое представление – «родное» для ПК, в котором любое вещественное число разбито на 3 части:
s exp m
s – знак числа (1 бит) exp – показатель степени
m – мантисса (дробная часть)
Встроенные в ТР вещественные типы данных
Идентификатор |
Диапазон представления |
Значащие |
Требуемый размер |
|
чисел |
цифры |
памяти (в байтах) |
|
|
мантиссы |
|
Single |
1.5 *10−45..3.4 *1038 |
7..8 |
4 |
Real |
2.9 *10−39..1.7 *1038 |
11..12 |
6 |
Double |
5.0 *10−324..1.7 *10308 |
15..16 |
8 |
Extended |
3.4 *10−4932..1.1*104932 |
19..20 |
10 |
Comp |
− 263 + 1..263 − 1 |
19..20 |
8 |
55
Все вещественные типы, за исключением типа real, можно использовать лишь при подключении математического сопроцессора. Чтобы подключить мат. сопроцессор, надо перед началом программы объявить директиву {$N+}7.
Не забывайте, что несмотря на то, что диапазон, например, чисел Real равен 1.5 *10−45..3.4 *1038 , это не означает, что все вещественные числа из этого диапазона могут быть записаны в разнесчастных 4 байтах8, которые занимает переменная этого типа. Не забывайте, что 4 байтами можно задать лишь 232 различных значений. Просто в мантиссе лишь первые 7-8 цифр будут точны, а все остальные могут быть какими угодно. Поэтому если вы захотите занести число в 100 знаков в тип extended то, несмотря на то, что диапазон значений у него огромный, но extended принципиально не может обеспечить того, чтобы младшие 80 знаков этого целого числа были нужного значения.
В ТР есть возможность печатать число не в стандартной записи, а используя специальный формат. Чтобы задать формат, надо после вещественного числа или вещественной переменной поставить :А:В, где А, В – целые числа, причем А – это количество символов, которые должны отводиться под число, а В – количество цифр в дробной части. Вторую часть формата можно не указывать.
Например, следующая строка
writeln(234.566:4:1);
напечатает число 234.566, округленное до десятых, т.е.
234.6.
Строка
writeln(234.566:4:5);
напечатает число, выделив под дробную часть 5 знаков:
234.56600
Заметьте, что первая часть формата была проигнорирована, т.к. она просто неверна и число не может быть умещено в 4 символа. Замечу, что первая часть формата (количество символов, которые отводятся под число), может использоваться и для целых чисел.
3.4. Ограничены ли вычислительные возможности компьютера?
Мы знаем, что:
•На любой тип данных существуют ограничения по величине числа. Для вещественных чисел есть, конечно, тип extended, которого должно хватить для практически любых расчетов. Но если надо, чтобы все вычисления проводились точно, то ограничение остается в силе.
•Числа вещественных типов на самом деле - рациональные, причем лишь их весьма небольшая часть.
•Иррациональные числа содержат бесконечное количество знаков после запятой, поэтому, например, число π нельзя точно записать в ПК (т.к. память – ограничена). Аналогичные рассуждения можно повторить для периодических дробей.
7 Директивы компилятора будут рассмотрены в главе 5.
8 Даже если бы у нас была бесконечная последовательность байтов a1, a2 ,..., an ,..., то и их тоже бы не хватило,
чтобы закодировать вещественные числа из любого сегмента.
56
Исходя из этих фактов, нередко заявляют, что в ПК невозможно представлять практически все числа и, следовательно, машинная арифметика имеет лишь ограниченное применение.
Давайте рассмотрим 3 вопроса:
1.Как описывать большие целые числа?
2.Как описывать периодические дроби?
3.Что делать с ограничением ПК в памяти и как представлять в ПК иррациональные числа?
1.Во-первых, большие числа можно легко задавать, используя массивы (глава 6). Тогда вы без проблем сможете работать с довольно большими числами, например, 1012332 . Именно задаче создания огромных чисел, с которыми при этом можно
работать с неимоверной точностью и посвящен первый проект «Длинная арифметика».
2.С рациональными числами - еще проще: дробь – это совокупность двух целых чисел – числителя и знаменателя. Причем в их качестве можно использовать числа, построенные в 1-м пункте. В главе 9 («Записи и модули») мы напишем модуль, позволяющий работать с дробями.
3.Когда математик говорит об иррациональных числах то он не выписывает все число (величина листа бумаги тоже может считаться ограничением на «память»), а
придумывает некоторое обозначение для него: 2 , log2 3 , π и т.д. И ничего не мешает придумать программисту любой тип данных, которых позволил бы реализовать, например, все радикалы любой степени вложенности. Разумеется, степень вложенности тоже ограничивается памятью, но этот довод я уже рассмотрел.
Единственное, что остается в защиту тезиса о «неполноценности машинной арифметики», - довод, который я назову «лингвистическим»: число можно описывать не только математическими символами, но и словами, например: «Пусть х – число, которое равняется количеству слов, которые используются в этой фразе, заключенной в кавычки, и которые имеют количество букв, большее 5» (т.е. х = 10). Это - серьезный довод. Можно научить компьютер распознавать определенные предложения, но суть тезиса в том, что на вход могут подаваться любые предложения. Этот тезис сводится к вопросу, может ли компьютер понимать прочитанный текст, или нет? Так как в определении могут фигурировать абсолютно любые слова и понятия, которые могут трактоваться по-разному в зависимости от контекста, то задать вопрос следовало бы так: возможен ли искусственный интеллект (ИИ)? Пока электронный мозг не создан, опровергнуть этот тезис полностью нельзя. А на сегодняшний день особых успехов на пути создания ИИ нет.
К вопросу о возможностях алгоритмических машин мы вернемся в главе 14.
3.5. Условный оператор
Вернемся от абстрактных рассуждений к делам будничным. Возможно, вы, тестируя программы, написанные вами в предыдущем разделе для разных начальных данных, заметили одну важную проблему: если, например, начальные значения катетов будут –3 и –4, то компьютер будет продолжать вычислять значения гипотенузы,
57
периметра и площади треугольника, не обращая внимание на то, что такие значения катетов недопустимы. Когда вы сами задаете значения катетов, используя константы, вы сами в ответе за правильность работы вашей программы. Однако, используя процедуру readln, мы не сможем гарантировать правильность ввода пользователем исходных данных, и программа выдаст неверный результат. Выход напрашивается сам собой: мы должны проверять введенные значения на правильность, и если они тест не прошли, программа должна уведомить пользователя о том, где была его ошибка. В ТР, как и в других императивных языках, механизм проверки условий существует, и реализуется с помощью условного оператора if.
Синтаксис условного оператора: if (условие) then
оператор1;
Работает условный оператор так: сначала проверяется следующее за ним условие. Если условие выполняется, тогда выполняется оператор1, в противном случае оператор1 выполняться не будет.
Если внутри условного оператора надо выполнить несколько действий, то применяется так называемый составной оператор:
begin
оператор 1; оператор 2;
. . . . .
оператор n; end
Его действие состоит в следующем: он несколько операторов объединяет в один. Вид оператора if, если мы используем составной оператор, будет следующий:
if (условие) then begin
оператор 1; оператор 2;
. . . . .
оператор n; end
Теперь можем модернизировать программу, вычисляющую конечную скорость и пройденное машиной расстояние, написанную нами на прошлом занятии.
Мы должны проверить входные данные на допустимость. Давайте рассмотрим, какие ограничения мы должны учесть. Мы упростим себе жизнь, и не будем учитывать ограничения на скорости и ускорения (хотя это стоило бы сделать, а не то пользователь может ввести такие начальные данные, при которых автомобиль сгорит в атмосфере). Учитывать будем лишь ограничение t>=0, т.е. нас будет интересовать положение автомобиля в будущем.
58
Пример 1: Программа, вычисляющая по v0, a, t скорость машины в конце пути и
пройденное ею расстояние.
1 : uses CRT;
2 : var
3 : S:real;
4 : v:real;
5 : v0:integer;
6 : a:shortint;
7 : t:integer;
8 : BEGIN
9 : Clrscr;{Очищаем экран}
10:write('Введите время движения машины (в сек.): ');
11:read(t);
12:write('Введите начальную скорость машины (в м/с): ');
13:read(v0);
14:write('Каково было ускорение (в м/(с*с))? ');
15:read(a);
16:if t<0 then
17:begin
18:writeln('Время не может быть <0');
19:exit;
20:end;
21:v:=v0+a*t;
22:S:=v0*t+(a*t*t/2);
23:writeln('Скорость в конце пути равна ',v,' м/с');
24:writeln('За время движения машина проехала ',S,' м');
25:END.
Отличия новой программы от старой:
•Время движения, начальная скорость и ускорение – переменные величины, которые вводит пользователь.
•В строке № 16 проверяется, правильно ли введено время. Мы предполагаем, что время отрицательным быть не может, поэтому если пользователь введет значение t<0, то программа должна выдать ему сообщение об ошибке и завершить свою работу. Так как должны быть выполнены 2 оператора, то надо использовать составной оператор. Выйти из программы можно с помощью процедуры exit. Если пользователь введет значение t>=0, то действия внутри оператора if выполняться не будут, и программа продолжит выполнение со строки 21.
Замечание: Если вам необходимо выполнять несколько операторов в теле оператора if, то не забывайте использовать составной оператор. Если вы напишете так:
if (условие) then
оператор1; оператор2;
то оператор1 будет вложен в оператор if, а оператор2 к оператору if относиться не будет.
59
3.6. Условный оператор с ветвью else
Часто требуется выполнять одни действия при выполнении условия, а другие – при его невыполнении. Для того, чтобы программист мог реализовать эту возможность, к оператору if присоединяется ветвь else.
Синтаксис такого условного оператора будет следующим: if условие then
оператор1 else
оператор2;
Замечание: Перед ключевым словом else “;” не ставится!!! Если “;” стоит, то компилятор выдает сообщение об ошибке (Error 113: Error in statement);
Алгоритм работы такого оператора следующий: проверяется условие, стоящее после ключевого слова if. Если оно выполняется, то выполняться будет оператор1, а оператор2 будет игнорироваться. В противном случае выполнятся будет оператор2, принадлежащий ветви else, а оператор1 выполняться не будет.
Если и основная ветвь условного оператора, и ветвь else содержат по несколько операторов, то условный оператор будет выглядеть так:
if (условие) then begin
оператор1; оператор2;
. . . . .
операторn; end
else begin
оператор1; оператор2;
. . . . .
операторn; end;
3.7. Делимость чисел. Операции div и mod
Вы уже знакомы с операцией деления ‘/’. Но если вы работаете с целыми числами, и вы хотите разделить одно число на другое, и при этом получить в результате другое целое число, то такая операция деления вам не подойдет, так как ее результат вещественный. Кроме того, часто при работе с целыми числами нужна операция нахождения остатка от деления одного целого числа на другое. Для решения этих проблем в ТР существуют операции div и mod.
Вэтом пункте будем рассматривать только целые числа.
•Говорят, что число a делится на число b (обозначается это aMb ), если существует число c такое, что a = bc .
•Число, на которое делится число x , называется делителем числа x .
•Число a называется кратным числу b , если a делится на b .
60
•Если a M2 , то число a называется четным. В противном случае a называется нечетным.
Пусть даны 2 числа a и b . Разделим столбиком число a на число b . Получим частное c и остаток от деления q . Тогда число a можно представить в виде a = bc + q .
Например:
-243 25 225 9 18
9 – частное от деления 243 на 25, 18 – остаток от деления, 243 = 25 9 +18 .
Операции нахождения частного и остатка от деления двух чисел, в ТР называются div и mod соответственно.
Например:
c:= |
243 |
div |
25; |
{c:=9} |
c:= |
243 |
mod |
25 |
{c:=18} |
С помощью операции mod можно легко реализовать проверку делимости чисел: aMb тогда и только тогда, когда (a mod b) =0.
В следующем примере пользователь вводит целое число, а компьютер отвечает, является ли оно четным или нечетным.
Пример 2: Проверка числа на четность.
1 : var
2 : n:integer;
3 : BEGIN
4 : writeln('Введите число');
5 : readln(n);
6 : if (n mod 2)=0 then {Если число делится на 2} 7 : writeln('Число - четное')
8 : else
9 : writeln('Число - нечетное');
10:readln;
11:End.
Если условие (n mod 2)=0 выполняется, то выводится сообщение «Число - четное». В противном случае выполняются операторы ветви else, т.е. выводится на экран сообщение «Число - нечетное».
3.8. Решение линейного уравнения
При решении уравнения ax + b = 0 , где a,b, x R , возможны 3 случая:
1.a ≠ 0 , тогда есть один корень x = − b
a
2.a = 0 , b ≠ 0 , тогда корней нет
3.a = 0 , b = 0 , то корни – все действительные числа.
Так как входные значения чисел а и b произвольные, то мы должны учесть все 3 случая.
Пример 3: Программа, которая решает линейное уравнение ax+b=0.
