Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль_для_математиков.DOC
Скачиваний:
12
Добавлен:
04.05.2019
Размер:
3.05 Mб
Скачать

18. Записи

Записи - это объекты, объединяющие данные разных типов. Записи состоят из полей. Описание записи имеет вид :

Record описания полей End;

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

Var c : Record

Name : String[40];

Phone : String[20];

End;

Type CoordType = Record x,y : Integer; End;

Var a : Array[1..3] Of CoordType;

Type PointType =

Record

c : CoordType;

Color : Word;

End;

Var T : PointType;

Чтобы обратиться в программе к полю записи, нужно использовать составное имя: имя записи . имя поля, например: c.Name[25] , a[2].x , T.c.y. Поэтому имена полей и не обязаны быть уникальными. Поля записей можно использовать точно так же, как и простые переменные того же типа. Однотипные записи можно присваивать друг другу. Иногда полные имена полей бывают довольно громоздкими и усложняют текст программы, этого можно избежать, используя оператор присоединения With, который записывается в виде:

With имя записи Do оператор/блок

Внутри оператора With можно использовать простые имена полей данной записи. Однако будьте осторожны, если имена полей не уникальны, любые имена, совпадающие с именем какого-нибудь поля записи, внутри оператора With всегда интерпретируются как имена полей, хотя вы, возможно, хотели использовать здесь имя простой переменной. Типизированные константы-записи допускаются и инициализируются в виде:

Const имя:тип=(имя поля:значение; имя поля:значение;...);

Опишем, например, константу типа PoinType :

Const p : PointType = (c:(x:100; y:20); Color:15);

Выведем эту константу :

WriteLn(p.c.x,p.c.y,p.Color);

или

With p Do WriteLn(c.x,c.y,Color);

или

With p.c Do WriteLn(x,y,p.Color);

Теперь решим более содержательную задачу: дано n точек на плоскости, каждая из которых покрашена в свой цвет, упорядочить точки по цвету, а точки одного цвета - по неубыванию радиус-вектора. Будем считать, что n не превосходит 100.

Type

CoordType = Record x,y : Real; End;

PointType = Record XY:CoordType; Color:Word; R:Real; End;

Var

p : Array[1..100] Of PointType;

Min : PointType;

n,i,j,Num : Byte;

Begin

Write('Введите количество точек ');

Read(n);

For i:=1 To n Do Begin

Write('Введите ',i:2,'-ю точку ');

With p[i] Do Read(XY.x,XY.y,Color);

End;

For i:=1 To n Do With p[i] Do

R:=Sqrt(Sqr(XY.x)+Sqr(XY.y));

For i:=1 To n-1 Do Begin

Min:=p[i];

Num:=i;

For j:=i+1 To n Do With p[j] Do

If (Color<Min.Color) Or (Color=Min.Color) And

(R<Min.R) Then Begin

Min:=p[j];

Num:=j;

End;

If Num<>i Then Begin

p[Num]:=p[i];

p[i]:=Min;

End;

End;

WriteLn('Упорядоченное множество точек :');

For i:=1 To n Do With p[i] Do WriteLn(XY.x:10:1,XY.y:10:1,Color:5);

End.

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

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. Сам способ описания вариантного поля, который в нашем примере имеет вполне дикий вид (это сделано намеренно), остался в языке Паскаль от его ранних диалектов, в которых все конструкции имели совершенно определенный смысл. Сейчас компилятору они не нужны, но тем не менее их необходимо записывать, чтобы не нарушать синтаксис языка.