Коднянко В.А.
Программирование на языке Object Pascal в среде Delphi

 

2. Система типов

    В языке Object Pascal все переменные, т. е. ячейки памяти, предназначенные для записи, чтения и хранения значений, должны быть предварительно описаны. Это означает, что всякая переменная должна быть явно отнесена к какому-либо типу.

    Тип – это одновременно структура и описание множества значений, которые могут быть присвоены такой переменной.

    Язык Object Pascal имеет множество разнообразных типов. Более того он позволяет самому пользователю конструировать самые разнообразные типы, которые могут быть ему необходимы. Конструирование таких типов производится из сравнительно ограниченного количества стандартных типов.

    Типы имеют свою иерархию. На верхнем этаже иерархии расположены следующие типы: простые, составные, ссылочные и процедурные.

    3. Стандартные простые типы

Основными типами языка являются стандартные простые типы и стандартные структурные типы.

Простые типы делятся на скалярные и ограниченные типы. Cкалярные типы делятся на стандартные и перечислимые. Стандартные скалярные типы делятся на пять видов:

  • целые [Integer],
  • вещественные [Real],
  • логический (булевский) [Boolean],
  • символьные [Char],
  • строковые [String].

К ним примыкает особый вариантный тип [Variant].

3.1. Целые типы

Эта группа типов охватывает множество целочисленных значений. Они отличаются друг от друга диапазоном допустимых значений и количеством занимаемой памяти.

Целыми типами являются ShortInt, SmallInt, LongInt, Int64, Byte, Word и LongWord, характеристики которых приведены в табл. 1.

 Таблица 1          

Тип

Диапазон значений

Размер памяти

1.

2.

3.

4.

5.

6.

7.

ShortInt

SmallInt

LongInt

Int64

Byte

Word

LongWord

–128 .. 127

–32768 .. 32767

–2147483648 .. 2147483647

–2^63 .. 2^63–1

0...255

0...65535

0 .. 4294967295

1 байт

2 байта

4 байта

8 байтов

1 байт

2 байта

4 байта

При назначении типа переменной следует исходить из оценки диапазона возможных значений, которые она может принимать в ходе выполнения программы.

Так если значения переменной будут только положительными, то можно ее отнести к одному из типов Byte, Word, LongWord. Если известно также, что ее значения никогда не выйдут за 255 (например, если переменная предназначена для хранения номера месяца текущего года), то лучше использовать тип Byte. При этом память будет расходоваться наиболее экономно.

Не следует, однако, стремиться к излишней экономии памяти на переменных. Нередко экономно описанная переменная может привести к ситуации, когда программа попытается записать в нее такую константу, которая превышает допустимый диапазон значений. Это приведет к немедленному аварийному завершению программы с сообщением "Range check error" (выход за допустимые границы диапазона). Сообщения такого рода могут генерироваться самыми разными операциями и в самых разных местах программы. По этой причине поиск ошибки в программе, особенно если она многомодульна и сложна, может надолго затянуться.

Не следует также злоупотреблять многообъемными типами, т.к. это может привести к излишнему перерасходу, а иногда и нехватке памяти, с одной стороны, и замедлению работы программы – с другой.

Примеры:

Var

A, A_Par: Integer;
T1, T2, T3: LongInt;
CircleCounter: byte;

Значения целых типов изображаются в обычном десятичном или в шестнадцатеричном видах. Они отличаются тем, что при изображении шестнадцатеричных значений в его начале ставится символ $ и сами значения формируются из шестнадцатеричных цифр 0 .. 9, A ... F.

Максимально допустимый диапазон значений определяется их типом.

Примеры:

0 9877             -56              $F1 ( то же, что 241)

Над целыми значениями можно выполнять четыре обыкновенных арифметических действия: сложение (+), вычитание (-), умножение (*), деление (/) и два дополнительных действия: деление нацело (div) и взятие остатка от деления (mod). При выполнении деления результатом будет вещественное значение, во всех остальных операциях – целое.

3.2. Вещественные типы

Эта группа типов охватывает вещественные значения.

Вещественные типы не могут быть использованы:

  • в качестве индексов массивов;
  • в операторах For и Case;
  • в качестве базисного типа при определении множеств;
  • при определении подтипов.

При описании вместо Real48 можно указывать Real.

Ниже в табл. 2 приведен список типов и их характеристики.

Таблица 2

Тип

Диапазон значений

Значащих цифр в мантиссе

Размер памяти

1.

2.

3.

4.

5.

6.

Real48

Single

Double

Extended

Comp

Currency

2.9 x 10^–39 ... 1.7 x 10^38

1.5 x 10^–45 ... 3.4 x 10^38

5.0 x 10^–324 ... 1.7 x 10^30

3.6 x 10^–4951 ... 1.1 x 10^4932

-2^63+1 ... 2^63 -1

-922337203685477.5808 ... 922337203685477.5807

11 – 12

7 – 8

15 – 16

19 – 20

19 – 20

19 – 20

6 байтов

4 байта

8 байтов

10 байтов

8 байтов

8 байтов

Примеры:

Var

rA, rA_Par: Real;
T: Integer;

Вещественные значения можно изобразить:

  • в форме с фиксированной десятичной точкой;
  • в форме с плавающей десятичной точкой.

Первая форма представления вещественного значения представляет привычное число, в котором целая и дробная части разделены десятичной точкой, например

12.455
-988.45
-8.0

Вторая форма предназначена для записи очень больших или очень маленьких по абсолютной величине значений, когда их представление в форме с фиксированной точкой затруднительно или невозможно. Такое значение изображают в виде

<значение с фиксированной точкой > E <порядок>

Примеры:

-45.2E6 ( то же, что -45,2 106)
5.245E-12 ( то же, что 5,24 10-12)

Порядок таких чисел должен быть всегда целым числом.

3.3. Логический (булевский) тип

Логические переменные имеют тип boolean. Такая переменная занимает один байт памяти и может иметь одно из двух возможных значений – True (истина) или False (ложь).

Примеры:

Var
b : boolean;
b1, Ti : boolean;

3.4. Символьный тип

Типы AnsiChar и WideChar описывают множество отдельных символов языка, включая буквы русского алфавита. AnsiChar описывает множество из 256 ASCII-кодов и занимает один байт памяти, WideChar описывает мно-жество Unicode – универсальное множество кодов и занимает два байта памя-ти. Тип AnsiChar эквивалентен базовому типу Char прежних версий языка.

Примеры:

Var
Ch, k : AnsiChar;
Char_Massivr: array[1..100] of Char;

Символьное значение представляют в виде символа, заключенного с обеих сторон в апострофы. Для изображения самого апострофа его удваивают (последний пример), например:

'h'      'X'       '#'      '$'       ''''

3.5. Строковые типы

Этот тип во многом схож с типом Array of Char, т. е. массивом символов. Отличие состоит в том, что переменная этого типа может иметь динамическое количество символов (от нуля до верхней границы), в то время как массив символов всегда статичен и имеет одинаковое количество символов.

Таблица 3       

Тип

Длина строки

Занимаемая память

1.

2.

3.

ShortString

AnsiString

WideString

0 – 256 символов

0 – 2 Гб символов

0 – 2 Гб символов

(Кол-во символов) х 1 байт

(Кол-во символов) х 1 байт

(Кол-во символов) х 2 байта

Максимальная длина строковой переменной должна быть указана явно. Размер строки на единицу больше ее объявленной длины, т. к. в ее нулевом байте содержится фактическая длина строки. Длину в нулевом байте можно принудительно менять.

Особо следует выделить тип String. Если длина String-строки не объявлена, то при действии директивы компилятора {$H+} или без ее указания такое объявление равносильно AnsiStrig. Если установлена директива {$H-}, то тип String равносилен типу ShortString.

Строковое значение изображают в виде последовательности символов, заключенной в апострофы. Пустую строку изображают двойным апострофом.

Примеры значений строковых типов:

'Иванов И.И.'      '' 'Газета"ИЗВЕСТИЯ"'       'Строка символов'

Примеры описания переменных строковых типов:

Var
s1, s2 : ShortString [12];
st1, st2 : AnsiString [580];
ChMassiv: array [1..15] of String;

3.6. Строковый тип PChar

Для связи с функциями Windows в язык Object Pascal введен новый тип строк – PChar-строки с завершающим нулем. В обычной и привычной для прежних версий языка String-строке нулевой байт отведен для хранения реального количества символов этой строки, а сами символы последовательно располагаются начиная с первого байта. В PChar-строке, наоборот, символы располагаются начиная с нулевого байта, а их последовательность заканчивается завершающим нулем.

Строки PChar можно объявлять как обычные символьные массивы. Например, строку длины 3000 плюс один байт, зарезервированный под завершающий нуль, можно определить следующим образом:

Var
s: array[1 .. 3000] of Char;

П р и м е ч а н и е. Без необходимости не используйте PChar-строки. Строковые String-типы и функции для обработки таких строк хорошо отлажены, они легче в использовании, и, как правило, надежнее PChar-строк.

3.7. Динамические PString-строки

Этот тип строк так же, как PChar, введен в язык для обращения к функциям Windows. Подробнее PString-строки описаны далее.

3.8. Перечислимые типы

Этот тип переменных может быть сформирован самим пользователем. Он создается простым перечислением возможных значений переменной.

Примеры перечислимых типов:

Type
MaleNames = (Ivan, Peter, Serge);
SwithOpts = (On, Off);
SostTypes = (Active, Passive, Waiting);
Sides = (Left, Right, Top, Down);

В первом примере переменная объявленного типа может принимать значение одного из трех мужских имен. Во втором – одно из двух значений – On (включено) или Off (выключено) и т. д.

Имена из списка перечислимого типа считаются константами соответствующего перечислимого типа и в пределах блока не должны повторяться.
Например, описания вида

Type
Days1 = (Monday, Wednesday, Friday);
Days2 = (Tuesday, Wednesday, Saturday, Sunday);

содержат ошибку, т. к. константа Wednesday используется дважды.

3.9. Ограниченные типы

Этот тип формируется самим пользователем посредством сужения значений ранее определенного или стандартного типов.

Примеры:

Type
Diapason = 1 .. 30;
Letters = 'a' .. 'v';
TList = (t1, t2, t3, t4, t5, t6,t7, t8, t9, t10);
TlistSmall = (t2 .. t8);

3.10. Вариантный тип (Variant)

Тип Variantособый тип языка Object Pascal. Значение этого типа наперед неизвестно, однако может быть определено через присваиваемое значение одним из следующих типов: все целые, вещественные, строковые, символьные и логические типы, за исключением Int64.

Следующие примеры демонстрируют использование типа Variant и механизм конверсии типов при смешивании его с другими типами. Сопроводи-тельные комментарии поясняют правила, при помощи которых операторы присваивания меняют тип Variant-переменных в зависимости от принятого ими значения.

Var
V1, V2, V3, V4, V5: Variant; {описание Variant-переменных }
I: Integer;
D: Double;
S: string;

...


begin
V1 := 1; { integer-значение }
V2 := 1234.5678; { real-значение }
V3 := 'Иванов'; { string-значение }
V4 := '1000'; { string-значение }
V5 := V1 + V2 + V4; { real-значение 2235.5678}
I := V1; { I = 1 (integer-значение) }
D := V2; { D = 1234.5678 (real-значение) }
S := V3; { S = ' Иванов' (string-значение) }
I := V4; { I = 1000 (integer-значение) }
S := V5; { S = '2235.5678' (string-значение) }
end;

3.11. Тип "дата время"

В языке имеется несколько типов, предназначенных для работы с датами и временем. Они имеют вид

Type
TDateTime = Double;
TDate = TDateTime;

TTimeStamp = Record
Time: Integer; { время в миллисекундах от полуночи }
Date: Integer; { единица + число дней с 01.01.0001 г.}
end;

Тип TDateTime предназначен для хранения даты и времени.

 

 

 

 

</body> </html>