назад

Глава 4. Типы


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

Указание идентификатора в левой части описания типа означает, что он определен как идентификатор типа для блока, в котором указано это описание типа. Область действия идентификатора типа не включает его самого, исключение составляют типы "указатель" (которые называют также ссылочными типами).

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


Простые типы

Простые типы определяют упорядоченные множества значений.

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

Примечание: В разделах "Числа" и "Строковые константы" Главы 2 вы можете найти описание того, как обозначать константы целого и вещественного типов.


Порядковые типы

Порядковые типы представляют собой подмножество простых типов. Все простые типы, отличные от вещественных типов, являются порядковыми и выделяются по следующим четырем характеристикам.

Синтаксис порядкового типа имеет следующий вид:

Borland Pascal имеет 10 встроенных порядковых типов: Integer (целое), Shortint (короткое целое), Longint (длинное целое), Byte (длиной в байт), Word (длиной в слово), Boolean (булевское), ByteBool (булевское размером в байт), WordBool (булевское размером в слово), LongBool (длинный булевский тип) и Char (символьный тип). Кроме того, имеется два других класса определяемых пользователем порядковых типов: перечислимые типы и отрезки типов (поддиапазоны).


Целочисленные типы

В Borland Pascal имеется пять предопределенных целочисленных типов: Shortint (короткое целое), Integer (целое), Longint (длинное целое), Byte (длиной в байт) и Word (длиной в слово). Каждый тип обозначает определенное подмножество целых чисел, как это показано в следующей таблице.

Таблица 4.1. Предопределенные целочисленные типы

Тип

Диапазон

Формат

короткое целое (Shortint)

-128 .. 127

8 бит со знаком

целое (Integer)

-32768 .. 32767

16 бит со знаком

длинное целое (Longint)

-2147483648 .. 2147483647

32 бита со знаком

длиной в байт (Byte)

0 .. 255

8 бит без знака

длиной в слово (Word)

0 .. 65535

16 бит без знака

Арифметические действия над операндами целочисленного типа предполагают 8-битовую, 16-битовую и 32-битовую точность в соответствии со следующими правилами:

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

Примечание: Приведение типов описывается в Главах 5 и 6.


Булевские типы

Существует 4 предопределенных булевских типа: Boolean, ByteBool, WordBool и LongBool. Значения булевского типа обозначаются встроенными идентификаторами констант False и True. Поскольку булевский тип является перечислимым, между этими значениями имеют место следующие отношения:

Переменные типа Boolean и ByteBool занимают 1 байт, переменная WordBool занимает два байта (слово), а переменная LongBool занимает четыре байта (два слова). Boolean - это наиболее предпочтительный тип, использующей меньше памяти; типа ByteBool, WordBool и LongBool обеспечивают совместимость с другими языками и средой Windows.

Предполагается, что переменная типа Boolean имеет порядковые значения 0 и 1, но переменные типа ByteBool, WordBool и LongBool могут иметь другие порядковые значения. Когда выражение типа ByteBool, WordBool или LongBool равна 1, то подразумевается, что она имеет значение True, а если оно равно 0 - то False. Когда значение типа ByteBool, WordBool или LongBool используется в контексте, где ожидается значение Boolean, компилятор будет автоматически генерировать код, преобразующий любое ненулевое значение в значение True.


Символьный тип (char)

Множеством значений этого типа являются символы, упорядоченные в соответствии с расширенным набором символов кода ASCII. При вызове функции Ord(Ch), где Ch - значение символьного типа, возвращается порядковый номер Ch.

Строковая константа с длиной 1 может обозначать значение константы символьного типа. Любое значение символьного типа может быть получено с помощью стандартной функции Chr.


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

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

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

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

Приведем пример перечислимого типа:

     type
        suit = (club, diamond, heart, spade);

Согласно этим описаниям diamond является константой типа suit.

При применении функции Ord к значению перечислимого типа Ord возвращает целое число, которое показывает, какое положение занимает это значение в отношении других значений этого перечислимого типа. Согласно предшествующим описаниям, Ord(club) возвращает 0, Ord(diamond) возвращает 1 и так далее.


Отрезки типа

Отрезок типа представляет собой диапазон значений из порядкового типа, называемого главным типом. Определение отрезка типа включает наименьшее и наибольшее значение в поддиапазоне. Оно имеет следующий синтаксис:

Обе константы должны иметь один и тот же порядковый тип. Отрезки типов, имеющие вид a..b, предполагают, что a меньше или равно b.

Приведем примеры отрезков типов:

     0..99
     -128..127
     club..heart

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

Разрешение использования выражений-констант там, где стандартный Паскаль допускает только простые константы, приводит к некоторой синтаксической неоднозначности. Рассмотрим следующие описания:

     const
        X = 50;
        Y = 10;
     type
        Color = (Red, Green, Blue);
        Scale = (X - Y) * 2..(X + Y) * 2;

Согласно синтаксису стандартного Паскаля, если определение типа начинается с круглой скобки, то это перечислимый тип (такой как Color в данном примере). Однако Scale предназначен для определения отрезка типа. Решение состоит в том, чтобы переупорядочить первое выражение поддиапазона или задать другую константу, равную значению данного выражения, и использовать эту константу в определении типа:

    type
        Scale = 2 * (X - Y)..(X + Y);

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

К вещественному типу относится подмножество вещественных чисел, которые могут быть представлены в формате с плавающей точкой с фиксированным числом цифр. Запись значения в формате с плавающей запятой обычно включает три значения - m, b и e - таким образом, что m x b^e=n, где b всегда равен 2, а m и e являются целочисленными значениями в диапазоне вещественного типа. Эти значения m и e далее определяют диапазон представления и точность вещественного типа.

Имеется пять видов вещественных типов: вещественное (Real), с одинарной точностью (Single), с двойной точностью (Double), с повышенной точностью (Extended) и сложное (Comp). Действия над типами с одинарной точностью, с двойной точностью и с повышенной точностью и над сложным типом могут выполняться только при наличии числового сопроцессора 8087 (который был описан ранее).

Вещественные типы различаются диапазоном и точностью связанных с ними значений (см. Таблицу 4.2).

Таблица 4.2. Диапазон представления и десятичные цифры для вещественных типов

Тип

Диапазон

Цифры

вещественное (Real)

2.9x10-39 .. 1.7x1038

от 11 до 12

с одинарной точностью (Single)

1.5x10-45 .. 3.4x1038

от 7 до 8

с двойной точностью (Double)

5.0x10-324 .. 1.7x10308

от 15 до 16

с повышенной точностью (Extended)

1.9x10-4951 .. 1.1x104932

от 19 до 20

сложный тип (Comp)

-263 + 1 .. 263 - 1

 

Примечание: Сложный тип содержит только целочисленные значения в диапазоне от -263+1 до 263-1, что приблизительно равно -9.2x1018 и 9.2x1018.

Borland Pascal поддерживает две модели генерации кода для выполнения действий над вещественными типами: программную для чисел с плавающей точкой и аппаратную для чисел с плавающей точкой. Выбор соответствующей модели осуществляется с помощью директивы компилятора $N.


Программная поддержка чисел с плавающей точкой

В состоянии {$N-}, которое устанавливается по умолчанию, генерируемый код выполняет все вычисления с вещественными типами программно, через вызов подпрограмм библиотеки исполняющей системы. Из-за соображений скорости и размера кода в этом состоянии допускаются только действия над переменными типа real (вещественное). Любая попытка оттранслировать операторы, выполняющие действия над типами с одинарной точностью, с двойной точностью, с повышенной точностью и над сложными типами, вызовет сообщение об ошибке.


Аппаратная поддержка чисел с плавающей точкой

В состоянии {$N+} генерируемый код выполняет все вычисления над вещественными типами с помощью числового сопроцессора 8087. Это состояние позволяет использовать все пять вещественных типов, однако оно требует наличия сопроцессора 8087 на этапе компиляции и выполнения.

Borland Pascal включает в себя библиотеки исполняющей системы, которые автоматически эмулируют программным путем сопроцессор 80х87, если при выполнении прикладной программы DOS реального или защищенного режима он отсутствует. Для определения того, следует ли в программу DOS включить эмулятор сопроцессора 80x87, используется директива компилятора $E. Если вы создает прикладную программу для реального или защищенного режима DOS, и сопроцессор 80х87 отсутствует, разрешение директивы компилятора $E обеспечи- вает полную программную эмуляцию сопроцессора 80x87. Для программ Windows директива $E не действует, так как Windows обеспечивает собственные подпрограммы эмуляции.

Примечание: Более детальное описание генерации кода при аппаратной поддержке чисел с плавающей запятой вы можете найти в Главе 15 "Использование сопроцессора 8087 в Borland Pascal".


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

Значением строкового типа является последовательность символов с динамическим атрибутом длины (в зависимости от действительного числа символов при выполнении программы) и постоянным атрибутом размера в диапазоне от 1 до 255. Текущее значение атрибута длины можно получить с помощью стандартной функции Length.

Примечание: Операторы работы со строковыми типами опи сываются разделах "Строковые операторы" и "Операторы отношений" Главы 6.

Отношение между любыми двумя строковыми значениями устанавливается согласно отношению порядка между значениями символов в соответствующих позициях. В двух строках разной длины каждый символ более длинной строки без соответствующего символа в более короткой строке принимает значение "больше"; например, 'Xs' больше, чем 'X'. Нулевые строки могут быть равны только другим нулевым строкам, и они являются наименьшими строковыми значениями.

Примечание: Стандартные процедуры и функции для работы со строковыми типами описаны в разделе "Строковые процедуры и функции".

К символам в строках можно обращаться как к элементам массива. См. раздел "Массивы, строки и индексы" в Главе 5.

К идентификатору строкового типа и к ссылке на переменную строкового типа можно применять стандартные функции Low и High. В этом случае функция Low возвращает 0, а High возвращает атрибут размера (максимальную длину) данной строки.

Параметр-переменная, описанная с помощью идентификатора OpenString и ключевого слова string в состоянии {$P+}, является открытым строковым параметром. Открытые строковые параметры позволяют передавать одной и той же процедуре или функции строковые переменные изменяющегося размера.

Примечание: Открытые строковые параметры описываются в Главе 9.


Структурные типы

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

Слово packed (упакованный) в описании структурного типа требует от компилятора уплотнить хранимые данные, даже за счет уменьшения скорости доступа к компоненту в переменной этого типа. Слово packed не имеет никакого действия в Borland Pascal, поскольку упаковка выполняется здесь автоматически всюду, где это возможно.


Типы массив

Массивы содержат фиксированное число элементов одного типа, так называемого типа элемента. На приводимой ниже синтаксической диаграмме тип элемента следует за словом of.

В индексных типах, по одному для каждой размерности массива, указывается число элементов. Допустимыми индексными типами являются все порядковые типы, за исключением длинного целого и поддиапазонов длинного целого. Массив может быть проиндексирован по каждой размерности всеми значениями соответствующего индексного типа; число элементов поэтому равно числу значений в каждом индексном типе. Число размерностей не ограничено.

Приведем пример типа массив:

     array[1..100] of Real

Если тип элемента в типе массив также является массивом, то результат можно рассматривать как массив массивов или как один многомерный массив. Например,

     array[boolean] of array[1..100] of array[Size] of Real

интерпретируется компилятором точно так же, как массив:

     array[boolean,1..10,Size] of Real

Кроме того, можно записать выражение:

     packed array[1..10] of packed array[1..8] of Boolean

как

     packed array[1..10,1..8] of Boolean

Для доступа к элементам массива необходимо указать идентификатор массива с одним или несколькими индексами в скобках (см. раздел "Массивы, строки и индексы").

Тип массив, имеющий вид:

     packed array[M..N] of Char

где M меньше N, называется упакованным строковым типом (слово packed можно опустить, поскольку оно не оказывает действия в Borland Pascal). Упакованный строковый тип имеет некоторые свойства, не характерные для других типов массив (см. раздел "Тождественные и совместимые типы" далее в этой главе).

Массив вида:

     array[0..X] of Char

где X - положительное целое число, называется массивом с нулевой базой. Массивы с нулевой базой используются для хранения строк с завершающим нулем, и, когда разрешен расширенный синтаксис (с помощью директивы компилятора {$X+}), символьный массив с нулевой базой совместим со значением типа PChar. Полностью эта тема обсуждается в Главе 18 "Использование строк с завершающим нулем".

Параметр, описанный с помощью синтаксиса array of T, называется открытым строковым параметром. Открытые строковые параметры позволяют передавать одной и той же процедуре или функции строковые переменные изменяющегося размера.

Примечание: Открытые строковые параметры описываются в Главе 9.


Типы запись

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

Фиксированная часть типа запись содержит список фиксированных полей вместе с идентификатором и типом для каждого поля. Каждое поле содержит информацию, которая всегда отыскивается одним и тем же способом.

Приведем пример типа запись:

     record
       year:  integer;          { год }
       month: 1..12;            { месяц }
       day:   1..31;            { число }
     end

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

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

В вариантной части можно указать необязательный идентификатор - идентификатор признака поля. При наличии идентификатора признака поля он становится идентификатором дополнительного фиксированного поля записи - поля признака. Программа может использовать значение поля признака для указания, какой вариант является активным в настоящий момент. Без указания поля признака программа выбирает вариант по другому критерию.

Ниже приводятся несколько примеров типов запись:

     record
       firstName,lastName : string[40];
       birthDate : Date;
       case citizen : boolean of
         True  : (birthPlace: string[40]);
         False : (country   : string[20];
                  entryPort : string[20];
                  entryDate : Date;
                  exitDate  : Date);
     end
 
     record
       x,y : real;
       case kind : Figure of
         rectangle : (height,wigth: real);     { прямоугольник }
         triangle : (size1,side2,angle: real); { треугольник }
         circle : (radius: real);              { круг }
     end

Множественные типы

Диапазон значений множественного типа представляет собой мощность множества для определенного порядкового типа (базового типа). Каждое возможное значение множественного типа является подмножеством возможных значений базового типа.

Переменная множественного типа может принимать как все значения множества, так и ни одного.

Базовый тип не должен иметь более 256 возможных значений, и порядковые значения верхней и нижней границы базового типа должны не превышать диапазона от 0 до 255. В силу этого базовый тип множества не может быть коротким целым (Shortint), целым (Integer), длинным целым (Longint) или словом (Word).

Примечание: Операции над множественными типами описываются в разделе "Операции над множествами" в Главе 6. В разделе "Описатели множеств" показано, как определять значения множества.

Любой множественный тип может принимать значение [], которое называется пустым множеством.


Файловые типы

Файловый тип состоит из линейной последовательности компонентов, которые могут иметь любой тип за исключением файлового типа или структурного типа, содержащего компонент с файловым типом. Число компонентов описанием файлового типа не устанавливается.

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

Стандартный файловый тип Text определяет файл, содержащий символы, упорядоченные в строки. Текстовые файлы используют специальные процедуры ввода-вывода, которые описываются в Главе 14 "Ввод и вывод".


Ссылочные типы

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

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

Переменной-указателю можно присвоить значение с помощью процедуры New, операции @ или функции Ptr. Процедура New отводит новую область памяти в динамически распределяемой области для динамических переменных и сохраняет адрес этой области в переменной указателя. Операция @ ориентирует переменную-указатель на область памяти, содержащую существующую переменную, включая и те переменные, которые имеют идентификаторы. Функция Ptr ориентирует переменную-указатель на определенный адрес в памяти.

Зарезервированное слово nil обозначает константу со значением указателя, которая ни на что не указывает.


Тип Pointer

Встроенный тип Pointer обозначает нетипизированный указатель, то есть указатель, который не указывает ни на какой определенный тип. Переменные типа Pointer могут быть разыменованы: указание символа ^ после такой переменной вызывает появление ошибки. Как и значение, обозначаемое словом nil, значения типа Pointer совместимы со всеми другими типами указателей.

Примечание: В разделе "Указатели и динамические переменные" в Главе 5 вы можете найти синтаксис ссылки на динамические переменные, которые указываются с помощью указателя-переменной.

Тип Pchar

Для представления указателя на строку с завершающим нулем в Borland Pascal имеется предопределенный тип PChar. В блоке System данный тип описывается следующим образом:

type PChar = ^Char;

Borland Pascal поддерживает набор расширенных правил, позволяющих работать со строками с завершающим нулем, используя тип PChar. Полностью эта тема обсуждается в Главе 18 "Использование строк с завершающим нулем".


Процедурные типы

В стандартном Паскале процедуры и функции рассматриваются только как части программы, которые можно выполнять с помощью вызова процедуры или функции. В Borland Pascal процедуры и функции трактуются гораздо шире: здесь допускается интерпретация процедур и функций, как объектов, которые можно присваивать переменным и передавать в качестве параметров. Такие действия можно выполнять с помощью процедурных типов.

В описании процедурного типа задаются параметры, а для функции - результат функции.

Характерно, что синтаксис записи процедурного типа в точности совпадает с записью заголовка процедуры или функции, только опускается идентификатор после ключевого слова procedure или function. Приведем некоторые примеры описаний процедурного типа:

     type
        Proc = procedure;
        SwapProc = procedure(var X, Y: Integer);
        StrProc = procedure(S: String);
        MathFunc = function(X: Real): Real;
        DeviceFunc = function(var F: text): Integer;
        MaxFunc = function(A, B: Real; F: MathFunc): Real;

Имена параметров в описании процедурного типа играют чисто декоративную роль - на смысл описание они не влияют.

Borland Pascal не позволяет описывать функции, которые возвращают значения процедурного типа. Результат функции должен быть строкового, вещественного, целого, символьного, булевского типа, указателем или иметь перечислимый тип, определенный пользователем.


Процедурные значения

Переменной процедурного типа можно присвоить процедурное значение. Процедурные значения могут быть следующими:

В контексте процедурных значений описание процедуры или функции можно рассматривать как специальный вид описаний констант, когда значением константы является процедура или функция. Рассмотрим, например, следующее описание:

     var
        P: SwapProc;
        F: MathFunc;
 
     procedure Swap(var A, B: Integer); far;
     var
       Temp: Integer;
     begin
       Temp := A;
       A := B;
       B := Temp;
     end;
 
     function Tan(Angle: Real); far;
     begin
       Tan := Sin(Angle) / Cos(Angle);
     end;

Переменным P и F можно присвоить значения следующим образом:

     P := Swap;
     F := Tan;

а вызовы с помощью P и F можно выполнить так:

     P(I, J);                  { эквивалентно Swap(I, J) }
     X := F(X);                { эквивалентно X := Tan(X) }

Использование процедурных переменных, которым в операторе вызова процедуры или функции присваивается значение nil, приводит к ошибке. Значение nil предназначено для указания того, что процедурная переменная не присвоена, и, так где процедурная переменная может получить значение nil, участвующие в этой процедурной переменной вызовы процедур и функций следует подвергать проверке:

     if @P <> nil then P(I, J);

Обратите внимание на использование операции @ для указания того, что P проверяется, а не вызывается.


Совместимость типов

Чтобы они считались совместимыми, процедурные типы должны иметь одно и то же число параметров, а параметры в соответствующих позициях должны иметь тождественные типы. При определении совместимости процедурных типов имена параметров значения не имеют. Значение nil совместимо с любым процедурным типом.

Чтобы использоваться в качестве процедурных значений, процедуры и функции должны описываться с директивой far и компилироваться в состоянии с {$F+}. Кроме того, в качестве процедурных значений не могут указываться стандартные процедуры и функции, вложенные процедуры и функции, методы, процедуры и функции, описанные с ключевым словом inline или interrupt.

Стандартные процедуры и функции - это подпрограммы, описанные в модуле Unit, например, WriteLn, ReadLn, Chr или Ord. Чтобы использовать в качестве процедурного значения стандартную процедуру и функцию, напишите для нее "оболочку". Например, следующая функция DSin совместима по присваиванию с описанным выше типом MathFunc:

     function FSin(X: Real): Real; far;
     begin
       FSin := Sin(X);
     end;

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


Тождественные и совместимые типы

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


Тождественность типов

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

Два типа, скажем T1 и T2, являются тождественными, если является истинным одно из следующих утверждений: T1 и T2 представляю собой один и тот же идентификатор типа; T1 описан как эквивалентный типу, тождественному T2.

Второе условие означает, что T1 не обязательно должен быть описан как непосредственно эквивалентный T2. Следующие описания типов:

     T1 = integer;
     T2 = T1;
     T3 = integer;
     T4 = T2;

означают, что T1, T2, T3, T4 и integer являются тождественными типами. Следующие описания типов:

     T5 = set of integer;
     T6 = set of integer;

не определяют T5 и T6 как тождественные, поскольку set of integer не является идентификатором типа. Две переменные, описанные в одном и том же описании, например:

     V1, V2: set of integer;

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

     V1: set of integer;
     V2: set of integer;
     V3: integer;
     V4: integer;

означают, что V3 и V4 имеют тождественный тип, а V1 и V2 - нет.


Совместимость типов

Иногда, например, в выражениях и операциях сравнения, требуется совместимость типов. Совместимость типов, кроме того, является важной предпосылкой для совместимости по присваиванию.

Совместимость типов имеет место, если выполняется по крайней мере одно из следующих условий:


Совместимость по присваиванию

Совместимость по присваиванию необходима, если имеет место присваивание значения, например, в операторе присваивания или при передаче значений параметров.

Значение типа T1 является совместимым по присваиванию с типом T2 (то есть допустим оператор T1:=T2), если выполняется одно из следующих условий:

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


Раздел описания типов

Программы, процедуры и функции имеют для описания типов специальный раздел описания типов. Например:

     type
       TRange     = integer;
       TNumber    = integer;
       TColor     = (red,green,blue);
       TTextIndex = 1..100;
       TTestValue = -99..99;
       TTestList  = array[TestIndex] of TestValue;
       PestList   = ^TTestList;
 
       TDate      = object
                       year: integer;
                       month: 1..12;
                       day: 1.. 31;
                     procedure SetDate(D, M, Y: Integer);
                     function ShowDate: String;
                     end;
 
     MeasureData = record
                     when: Date;
                     count: TTestIndex;
                     data: TestListPtr;
                   end;
     TMeasureList = array[1..50] of MeasureData;
     TName        = string[80];
     TSex         = (male,female);
     TPersonDate  = ^TPersonData;
     TPersonData  = record
                     name,firstName: TName;
                     age:            integer;
                     married:        boolean;
                     father,child,sibling: Person;
                       case s: Sex of
                         male:   (bearded: boolean);
                         female: (pregnant: boolean);
                    end;
     TPersonDate = array[0..SizeOf(TPersonDate)-1] of Byte;
     TPeople  = file of TPersonData;

В этом примере Range, Number и Integer являются тождественными типами. TTestIndex является просто совместимым и совместимым по присваиванию, но не тождественным, с типами Number, Range и Integer. Обратите внимание на использование в описаниях TcharVal и TPersonBuf выражений-констант.

 

Hosted by uCoz