Основы Object Pascal (551739), страница 3
Текст из файла (страница 3)
Несмотря на то, что Pascal не чувствителен к регистру, старайтесь использовать заглавные буквы для того чтобы придать Вашим идентификаторам выразительность. Согласитесь, что идентификаторы EarthMeanRadius или Earth_Mean_Radius привлекательней чем earthmeanradius.
Типы данных и переменные
НОВЫЙ ТЕРМИН. В Object Pascal тип данных информирует компилятор как размещать информацию в памяти.
Некоторые языки программирования допускают присваивание переменной значения любого типа. Например, рассмотрим следующие примеры кода на языке BASIC:
X = -1;
X = 1000;
X = 3.14;
Интерпретатор BASIC заботится о выделении подходящего размера памяти для хранения соответствующего значения.
В программе на Object Pascal все переменные, используемые в программе надо объявить, например
var
X1 : Integer;
X : Integer;
Y : Double;
Z : Byte;
{ ...далее }
X1 := -1;
X := 1000;
Y := 3.14;
Z := 27;
Компилятор использует объявления переменных для проверки корректности присваиваемых им значений. Некорректность использования типов данных приведет либо к ошибке компиляции, либо к предупреждению, на которое следует обратить внимание, проанализировать и исправить ошибку. Строгий контроль за использованием типов данных обеспечивает надежность программы.
Некоторые из типов являются беззнаковыми, т.е. данные такого типа могут принимать только положительные значения. В таблице 1.1 приведены основные типы данных Object Pascal, размер памяти для размещения одного значения соответствующего типа, а так же диапазон допустимых значений. В этой таблице не представлены строковые типы, обсуждение которых вынесено в раздел «Строки»
Таблица 1.1. Типы данных Object Pascal
Тип | Размер, байт | Диапазон значений |
ShortInt | 1 | -128 …127 |
Byte | 1 | 0 … 255 |
Char | 1 | 0 … 255 |
WideChar | 2 | 0 … 65 535 |
SmallInt | 2 | –32 768 … 32 767 |
Word | 2 | 0 … 65 535 |
LongInt | 4 | –2 147 483 648 … 2 147 483 647 |
Int64 | 8 | от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 |
Integer | 4 | см. LongInt |
Cardinal | 4 | 0 … 2 147 483 647 |
Single | 4 | 1.5 10-45 … 3.4 1038 |
Double | 8 | 5.0 10-324 … 1.7 10308 |
Real | 8 | как Double |
Extended | 10 | 3.4 10-4932 … 1.1 104932 |
Comp | 8 | от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 |
Currency | 8 | от –922 337 203 685 477.5808 до 922 337 203 685 477.5807 |
Boolean | 1 | True или False |
Variant | 16 |
Как следует из таблицы 1.1, типы Integer и LongInt эквивалентны. Это сделано для совместимости на уровне исходных текстов с программами, подготовленными на 16–разрядных компьютерах. На 16–разрядной версии тип Integer требует 2 байта памяти, а тип LongInt – 4 байта.
В 32-разрядной версии оба типа имеют размер 4 байта и, следовательно, одинаковые диапазоны значений.
Кроме того, можно заметить, что типы Int64 и Comp (computational) также имеют одинаковые диапазоны значений. Различие между ними в том как трактует их компилятор. Так, Int64 относится к целочисленным, а тип Comp – к вещественным. В инженерных приложениях тип Comp вряд ли Вам понадобится.
Далее, отметим идентичность типов Real и Double. В Delphi 1.0 (и в Turbo Pascal) тип Real был 6-байтным. Теперь он стал 8-байтным. Дело в том, что 6-байтный вещественный тип противоречит 32-разрядной архитектуре современных процессоров.
При переносе «старых» 16-разрядных программ на 32-разрядную платформу может возникнуть проблема совместимости по типу real. Так, если в Delphi – программе вы читаете с диска «старый» типизированный файл, объявленный как file of real, данные будут введены не верно. Для совместимости со «старым» типом real в Object Pascal есть тип real48, который соответствует 6–байтному вещественному числу.
ПРИМЕЧАНИЕ. Тип Int64 впервые появился в Delphi 4. Он предназначен для представления «очень больших» целочисленных значений. Его появление связано с тем, что объем жестких дисков далеко «перевалил» за гигабайт. В Windows API есть функция GetDiskFreeSpaceEx, которая вычисляет объем свободного пространства на жестком диске. Она может вернуть значение, которое гораздо больше верхней границы диапазона чисел типа Integer (2 147 483 647). Тип 64-битного целого и предназначен для решения подобных проблем.
Типы Single, Double, Extended, и Currency относятся к группе вещественных. К данным этого типа относятся числа, имеющие целую и дробную части. Каждое число вещественного типа может содержать конечное число десятичных цифр. Иначе данные этого типа называют числами с плавающей точкой.
Остальные типы данных относятся к целочисленным. Целочисленной переменной нельзя присвоить вещественное значение. Например, при компиляции следующего фрагмента будет зафиксирована ошибка:
var
X : Integer;
{ Далее... }
X := 3.75;
При написании кода программы, который отвечает за графический интерфейс, необходимость в переменных вещественного типа возникает очень редко.
С другой стороны, код реализации инженерных расчетов оперирует вещественными переменными на все 100%.
Преобразование типов
Если это не противоречит правилам, Object Pascal автоматически преобразует значения одного типа в значения других типов.
Рассмотрим следующий фрагмент кода:
var
Res : SmallInt;
Num1 : Integer;
Num2 : Integer;
{ далее... }
Num1 := 200;
Num2 := 200;
Res := Num1 * Num2;
Здесь результат умножения двух чисел типа Integer присваивается переменной типа SmallInt. Несмотря на смесь типов, Object Pascal способен выполнить преобразование.
Вопрос: Какое значение получит переменная Res?.
Ответ: -25536.
Почему?
В таблице 1.1 указано, что максимальным значением типа SmallInt является число 32767. При добавлении единицы к числу 32767 типа SmallInt мы получим –32768, что соответствует нижней границе диапазона чисел этого типа. Это в точности соответствует поведению счетчика километража на спидометре автомобиля когда при пробеге последнего из первой сотни тысяч километров показание 99 999 сбрасывается на 00 000.
Выполните следующие упражнение:
1. Создайте новый проект. Поместите на форму надпись и кнопку.
2. Дважды щелкните на кнопке формы чтобы перейти в режим редактирования обработчика события OnClick.
3. Придайте обработчику события OnClick такой вид :
procedure TForm1.Button1Click(Sender: TObject);
var
X : SmallInt;
begin
X := 32767;
X := X + 1;
Label1.Caption := IntToStr(X);
end;
4. Скомпилируйте программу и нажмите кнопку Button1.
Вы должны увидеть, что после щелчка на кнопке надпись показывает -32768 (функция IntToStr здесь преобразует целое значение в строковое). Итак, мы убедились в том, что 32767 + 1 = -32768 !
Данное упражнение иллюстрирует эффект целочисленного переполнения (overflow wrapping).
При использовании переменных целого типа всегда надо помнить об ограниченности диапазонов их значений.
Иногда преобразование данных одного типа в другой недопустимо. В такой ситуации вы увидите диагностику (сообщение об ошибке) вроде
Incompatible types: Integer and Real.
Это сообщение информирует о том, что была сделана попытка присвоить переменной значение, тип которого не соответствует типу этой переменной.
Если некорректность использования данных целочисленных типов может быть выявлена на этапе компиляции программы, вы увидите сообщение вроде «Range checking error»
Например, при компиляции фрагмента
var
X : Byte;
begin
X := 1000;
end;
будет выдано сообщение:
Constant expression violates subrange bounds.
Тем самым, компилятор информирует нас о том, что переменной X типа byte нельзя присвоить значение 1000, ибо переменные этого типа могут принимать любые значения только в диапазоне от 0 до 255.
ВНИМАНИЕ! Компилятор генерирует диагностические сообщения трех уровней серьезности: hint, warning и error.
-
hint – подсказка. Это что-то вроде «Обратите внимание на …»
-
warning – это предупреждение (серьезней чем hint)
-
error – это ошибка.
В первых двух случаях исполняемый файл все же создается, т.е. программа будет работать, но, возможно, некорректно. В последнем случае компилятор не сможет создать исполняемый файл.
Попробуйте заставить себя трактовать «hints » и «warnings » как сообщения о потенциальных ошибках в программе. Сообщениями этого типа компилятор «пытается» информировать вас о том, что в исходном тексте программы что-то не так, но это не страшно. Тем не менее, разберитесь в причине появления подсказки или предупреждения и устраните ее. Ситуации, когда предупреждения можно просто игнорировать, встречаются достаточно редко.
Знаки операций
С помощью знаков операций выполняют вычисления, сравнивают значения и т.д. Object Pascal предоставляет программисту большой набор операций над данными. Сначала рассмотрим те из них, которые применяются наиболее часто. Их список дан в таблице 1.2.
Таблица 1.2. Знаки операций
Символ | Описание | Пример |
Математические | ||
+ | Сложение | x := y + z; |
- | Вычитание | x := y - z; |
* | Умножение | x := y * z; |
/ | Вещественное деление | x := y / 3.14; |
div | Целочисленное деление | x := y div 10; |
Присваивание | ||
:= | Присвоить | x := 10; |
Логические | ||
and | Логическое «И» | if (x=1) and (y=2) then ... |
or | Логическое «ИЛИ» | if (x=1) or (y=2) then ... |
xor | Исключающее «ИЛИ» | if (x=1) xor (y<=2) then .. |
Битовые | ||
and | Поразрядное «И» | x := x and $02; |
or | Поразрядное «ИЛИ» | x := x or $FF; |
xor | Сложение по модулю 2 | x := x xor $AB |
Сравнения | ||
= | Равно | if (x = 10) then ... |
<> | Не равно | if (x <> 10) then ... |
< | Меньше чем | if (x < 10) then ... |
> | Больше чем | if (x > 10) then ... |
<= | Меньше или равно | if (x <= 10) then ... |
>= | Больше или равно | if (x >= 10) then ... |
Одноместные | ||
^ | Разыменование ссылки | MyObject.Data^; |
@ | Адрес | ptr := @MyRecord; |
not | Поразрядное отрицание | x := x and not $02; |
not | Логическое отрицание | if not Valid then ... |
Другие | ||
$ | Шестнадцатеричное число | X := $FF; |
[] | Индекс элемента массива | X := MyArray[5]; |
. | Точка – соединение полей | X := Record.Data; |
Список операций достаточно внушителен. Учить его наизусть нет необходимости. Все эти операции вы постепенно научитесь использовать в процессе создания различных программ. Необходимость применения ряда операций возникает очень редко. Но есть и такие, которые необходимы постоянно.