Иллюстрированный самоучитель по Турбо Паскалю
Преобразованя типов и действия над ними
Как уже говорилось, тип переменной позволяет не только устанавливать длину ее
внутреннего представления, но и контролировать те действия, которые выполняются
над ней в программе. Контроль за использованием переменных еще на этапе
компиляции программы - важное преимущество Турбо Паскаля перед другими языками
программирования, в которых допускается автоматическое преобразование типов. В
Турбо Паскале почти невозможны неявные (автоматические) преобразования типов.
Исключение сделано только в отношении констант и переменных типа INTEGER
(целые), которые разрешается использовать в выражениях типа REAL (вещественные).
Если, например, переменные X и Y описаны следующим образом:
var
х: Integer;
у: Real;
то оператор
у := х + 2;
будет синтаксически правильным: хотя справа от знака присваивания стоит
целочисленное выражение, а слева - вещественная переменная, компилятор сделает
необходимые преобразования автоматически. В то же время оператор
х := 2.0;
будет неверным, так как автоматическое преобразование типа REAL (константа
2.0 содержит десятичную точку и, следовательно, принадлежит к типу REAL) в тип
INTEGER в Турбо Паскале запрещено.
Разумеется, запрет на автоматическое преобразование типов еще не означает,
что в Турбо Паскале нет средств преобразования данных. Они, конечно же, есть, но
их нужно использовать явно (подробнее об этом см. гл.4). Для преобразования
данных в языке существуют встроенные функции, которые получают в качестве
параметра значение одного типа, а возвращают результат в виде значения другого
типа. В частности, для преобразования REAL в INTEGER имеются даже две встроенные
функции такого рода: ROUND округляет REAL до ближайшего целого, a TRUNC усекает
REAL путем отбрасывания дробной части.
Например, ошибочным будет оператор
х := у/х;
но правильным
х := round(у/х);
(объявления переменных см. выше).
Понятие функции в Турбо Паскале близко к понятию процедуры. Как и
процедура, функция вызывается своим именем и может содержать произвольное число
операторов Турбо Паскаля и даже внутренних процедур и функций. Существенным
отличием функции от процедуры является то обстоятельство, что функция имеет
собственное значение и, следовательно, может использоваться наравне с
переменными в выражениях соответствующего типа.
Для преобразования данных типа CHAR (символ) в целое число предназначена
функция ORD, обратное преобразование INTEGER в CHAR осуществляет функция CHR.
С помощью следующей несложной программы (пример 2.3) Вы сможете узнать
внутренний код произвольного символа.
Пример 2.3
Program Code_pf_Char;
{Программа читает символ с клавиатуры и выводит на экран
этот символ несоответствующий ему внутренний код}
var
ch: Char; {В эту переменную читается символ}
begin
Write('Введите любой символ: ');
ReadLn(ch); {Читаем один символ}
WriteLn(ch,
' = ',ord(ch)); {Преобразуем его к
целому и выводим на экран}
END.
Обратите внимание: при вызове
WriteLntch,' = ',ord(ch));
третьим параметром обращения указан вызов функции ORD (СН) , что с точки
зрения языка является выражением; как мы увидим дальше (см. гл.8), во многих
случаях при вызове процедур и функций в качестве параметров вызова можно
указывать не только переменные или константы, но и выражения с их участием.
По мере надобности мы будем знакомиться с другими функциями преобразования
типов данных, а сейчас - о тех операциях, которые разрешены над различными
типами.
Конечно же, в Турбо Паскале есть все четыре арифметические операции над
переменными REAL И INTEGER:
+ - сложение;
- - вычитание;
* - умножение;
/ - деление вещественное;
div -
деление целочисленное.
Наличие двух операций деления есть еще одно проявление основополагающего
принципа Турбо Паскаля: программист должен явно подтверждать компилятору, что он
готов к возможным последствиям преобразования типов. Если, например, в языке
Фортран используется выражение 1/2 , то результат этого выражения будет зависеть
от того, переменной какого типа он будет присвоен: если N есть переменная целого
типа, а Х- вещественного, то в программе на Фортране присваивания
N = 1/2
X = 1/2
дадут значения 0 для N и 0.5 для X. В Турбо Паскале такой двусмысленности
нет: выражение 1/2 всегда имеет значение 0.5 и поэтому оператор
var
N :Integer;
begin
N := 1/2;
просто недопустим. В то же время допустимый в Турбо Паскале оператор
var
X : Real;
begin
X := 1 div 2;
самим фактом использования операции целочисленного деления DIV
свидетельствует о том, что программист сознательно отбрасывает дробную часть
результата. (Надеюсь, что читатель извинит явную искусственность этих примеров,
которая вызвана лишь стремлением проиллюстрировать обсуждаемые особенности
языка).
Для данных типа INTEGER в Турбо Паскале есть еще одна операция MOD -
получение остатка от целочисленного деления. Например:
5 mod 2 = 1
31 mod 16 = 15
18 mod 3 = 0
В Турбо Паскале отсутствует операция возведения в степень, что, очевидно,
будет вызывать определенные неудобства при реализации вычислительных алгоритмов.
Некоторым утешением может служить наличие встроенной функции SQR, возвращающей
квадрат от значения параметра, причем тип результата определяется типом
параметра.
И еще об одном существенном недостатке Турбо Паскаля: в нем отсутствуют
комплексный тип и соответствующие операции над ним. Вообще, в отношении
реализации разнообразных вычислительных процедур Турбо Паскаль значительно
уступает некоторым другим языкам программирования, в частности, тому же
Фортрану. В частности, в нем намного беднее набор встроенных математических
функций (см. гл. 4).
При работе с целыми числами могут оказаться полезными две процедуры (здесь и
далее в квадратных скобках указываются необязательные параметры):
DEC (X [, N] ) - уменьшает содержимое переменной X на значение выражения N
(если N не задано, то на 1); тип переменной X и выражения N - INTEGER (точнее,
любой целый, см. гл. 4);
INC (X [, N] ) - увеличивает значение X на N (если N не задано, то на 1).
Над символами и строками символов определена единственная операция -
сцепление двух строк. Операция обозначается символом «+». Например, программа
var
st: String;
begin
st := 'Турбо'+'-'+'Паскаль';
WriteLn(st);
end.
напечатает строку
Турбо-Паскаль
Все остальные действия над строками и символами реализуются с помощью
встроенных процедур и функций (см. гл.4).
И, наконец, об операциях отношения и логических операциях.
Над данными типа REAL, INTEGER, CHAR, STRING определены следующие операции
отношения (сравнения):
= - равно;
<> - не равно;
< - меньше;
> - больше;
<= - меньше или равно,
>= - больше или равно.
В операциях сравнения должны участвовать однотипные операнды. Исключение
сделано опять-таки в отношении REAL и INTEGER, которые могут сравниваться друг с
другом. Результат применения операции отношения к любым операндам имеет тип
BOOLEAN.
Сравнение двух строк осуществляется следующим образом. Символы строк
сравниваются попарно друг с другом так, что первый символ первой строки
сравнивается с первым символом второй строки, второй символ первой строки - со
вторым символом второй и т.д. Символы сравниваются путем сравнения их кодов во
внутреннем представлении (см. гл. 4). Если одна строка короче другой,
недостающие символы заменяются нулем. Отношение первой несовпадающей друг с
другом пары символов и принимается за отношение двух строк.
При сравнении данных типа BOOLEAN учитывается внутреннее соглашение Турбо
Паскаля, в соответствии с которым FALSE есть нулевой байт, a TRUE - байт с
единицей в младшем разряде. Заметим, что функция ORD преобразует к целому не
только символы, но и логические величины, поэтому
ord(false) = 0,
ord(true) = 1.
В Турбо Паскале определены следующие логические операции:
not - логическое НЕ;
or - логическое ИЛИ;
and - логическое И;
хоr - исключающее ИЛИ.
Логические операции применимы к операндам целого и логического типов. Если
операнды - целые числа, то результат логической операции есть тоже целое число
(подробнее об этом сказано в гл.4). Логические операции над логическими данными
дают результат логического типа.
При вычислении выражений любого типа приоритет вычислений определяется
расставленными скобками, а при их отсутствии - по табл. 2.1 (в порядке убывания
приоритета).
Таблица 2.1 Приоритет операций
Приоритет |
Операция |
1 |
not, @ |
2 |
*, /, div, mod, and, shl , shr |
3 |
+, - , or, xor |
4 |
=, <>, >, >=, <, <=, in |
Примечание. Операции @ (получение адреса), shl (сдвиг влево), shr (сдвиг
вправо) и in (принадлежность к множеству) описаны в гл.4.
Следует учесть, что в отличие от многих других языков программирования в
Турбо Паскале логические операции имеют более высокий приоритет, чем операции
отношения. В связи с этим, в сложных логических выражениях обычно необходимо
расставлять скобки. Если, например, b и с имеют тип INTEGER , то выражение
а = b and с < d
вызовет сообщение о синтаксической ошибке, так как сначала выполнится
операция b and с. Правильным будет выражение:
(а = b) and (с < d)