Case тип Of

константа 1 : (описание поля);

константа 2 : (описание поля);

..................................

 

Здесь тип - любой порядковый тип (фактически компилятор Паскаля никак не использует этот тип, поэтому можно всегда писать, например, Byte); константа 1, константа 2 и т.д. - это любые константы порядкового типа (их значение также не используется компилятором). Запись может иметь только одно вариантное поле, и это поле должно быть последним. Память для размещения вариантного поля отводится по самому большому варианту. Приведем пример использования такой записи:

 

Var z : Record x,y : Integer;

Case Byte Of

0 : (L : LongInt);

True : (W : Array[0..1] Of Word);

'D' : (B0: Byte; B : Array[0..3] Of Byte);

-22 : (S : String);

End;

Begin

z.S:='12345';

With z Do WriteLn(B0,B[0]:3,B[1]:3,B[2]:3,B[3]:3,' ',S);

z.L:=1000;

With z Do WriteLn(L,' ',W[0],' ',W[1]);

End.

 

Программа выведет : 5 49 50 51 52 12345

1000 1000 0

Действительно, в первом байте вариантного поля первоначально хранилась длина строки - 5, а в следующих четырех - символы '1','2','3','4', т.е. байты 49-52. После выполнения второго оператора присваивания в младшем слове оказалось число 1000, а в старшем - 0. Фактически вариантное поле занимает256 байт памяти, но при обращении к нему по имениL и W нам доступны первые 4 байта, а при обращении по имени B - первые 5 байт.

Таким образом, вариантное поле - это некоторый участок памяти, к которому можно обращаться с разными именами, каждое имя однозначно связано с определенным типом. Значение, хранящееся в этом участке памяти, конечно, в каждый момент времени совершенно определенное и не зависит от способа обращения, но интерпретация этой последовательности байтов зависит от используемого типа. Мы уже знаем, что того же результата можно добиться, используя описатель Absolute. Сам способ описания вариантного поля, который в нашем примере имеет вполне дикий вид (это сделано намеренно), остался в языке Паскаль от его ранних диалектов, в которых все конструкции имели совершенно определенный смысл. Сейчас компилятору они не нужны, но тем не менее их необходимо записывать, чтобы не нарушать синтаксис языка.

19. Тип "перечисление"

Тип “перечисление” описывается в виде:

(идентификатор1,...,идентификаторN)

Идентификаторы, использованные при описании типа, автоматически становятся константами этого типа. Можно использовать в программе переменные и именованные константы типа “перечисление”. К ним применимы функции Ord, Pred и Succ. Переменной можно присвоить значение ее типа; такие переменные могут быть переменными цикла; тип “перечисление” может быть базовым типом множества. Но переменные типа “перечисление” нельзя вводить и выводить, они не могут быть преобразованы ни к какому другому типу. Попробуем использовать тип “перечисление” :

 

Type Months = (Jan,Feb,Mar,Apr,Mai,Jun,Jul,Aug,Sep,Oct,Nov,Dec);

{идентификаторы Jan...Dec стали КОНСТАНТАМИ типа Months}

Var M : Months;

Const MM : Months = Mar;

Type M_Set = Set Of Months;

Const Sem1 : M_Set = [Sep..Dec];

Sem2 : M_Set = [Feb..Mai];

Sess : M_Set = [Jan,Jun];

Const Year : Byte=0;

Begin {определим, что за месяц MM}

If MM In Sem1 Then WriteLn('1-й семестр') Else

If MM In Sem2 Then WriteLn('2-й семестр') Else

If MM In Sess Then WriteLn('сессия') Else

WriteLn('каникулы');

{посчитаем продолжительность учебного года}

For M:=Jan To Dec Do

If M In Sem1+Sem2+Sess Then Inc(Year);

WriteLn('Учебный год длится ',Year,' месяцев');

End.