Поля записи и доступ к ним. Оператор присоединения
Доступ к полям записи осуществляется через расширенное имя – это имя записи и имя поля разделённые точкой. В том случае, если доступ к полям записи осуществляется многократно, целесообразно обращаться к полям записи с использованием оператора присоединения with. Например, для переменной Sofr типа Human возможны следующие варианты доступа к полю Day с применением оператора with:
а) with Sotr do BirlhDay.Day:= 30;
б) with Sotr.BirthDay do Day:= 24;
в) with Sotr, BirlhDay do Daay:=31;
г) with Sotr do with BirthDay do Day:= 7; ...
Операция возможна при совпадении типов записей и выполняется последовательно поле за полем.
Ввод записей с клавиатуры и вывод их на экран выполняются по полям по правилам ввода переменных соответствующих типов.
Пример. Разработать программу, которая вводит в массив записей информацию о студентах учебной группы: фамилию и дату рождения. Организовать поиск информации о студенте, фамилия которого вводится с клавиатуры.
type data = record {тип запись данные о дате}
year: word; {год}
month: 1 .. 12; {месяц}
day: 1 .. 31; {день}
end;
zap = record {тип запись о студенте}
fam: string [16]; {фамилия}
birthday: data; {дата рождения}
end;
Var fb: array [1..25] of zap; { массив данных о группе студентов}
fff: string; {строка для ввода фамилии}
i, j, m, h: byte;
key: boolean; {ключ поиска, если фамилия найдена - true}
Begin
WriteLn('Введите данные о количестве студентов n<=25');
ReadLn(n);
m:=0;
{ввод исходных данных с клавиатуры поле за полем}
repeat
m:= m + 1;
Write (´Введите фамичию: '); Readln(fb[m].fam);
Write ('Введите год рождения: '); Readln(fb[m].birthday.year);
Write ('месяц:'); Readln(fb[m].birthday.month);
Write ('день. '); Readln(fb[m].birthday.day);
until n = m;
WriteLn;
{'выход исходных данных на экране с помощью оператора with}
Writeln( 'Список студентов группы ');
Writeln;
For i:=l to m do
with fb[i] do
begin
Write(i:2,fam:l7);
with birthday do
Writeln(year:6, month :4, day:4);
end;
Writeln;
{поиск данных в массиве записей}
Writeln('Введите фамилию');
Readln(fff);
i:=0;
key:=false; {признак «данные не найдены»}
repeat i:=i + l;
if fb[i].fam = fff then key:=true
until key or( i = m);
{вывод результата}
if key then {если такой студент найден, то выводим данные}
with fb[i] do
begin
Writeln ('Данные о студенте:');
Write (fam:18,' ')
with birthday do
Writeln(day:2,': ', month:2, ': ', year:5,' года');
End
else WriteLn('Данных о студенте: ', fff:l8,' нет.');
End.
Записи с вариантными полями. Правила описания вариантной части
Иногда бынает удобно и естественно рассматривать несколько типов данных как варианты одного, т. е. в пределах одной записи иметь различную информацию в зависимости от конкретного значения некоторых полей. Для обеспечения такой возможности запись кроме фиксированного списка полей может иметь еще и вариантную часть.
Вариантная часть может содержать несколько альтернатив, в каждой из которых задается список полей, присущих данному варианту. Каждой альтернативе предшествует константа, идентифицирующая соответствующий вариант.
Рассмотрим несколько примеров определения записей с вариантами:
§ без предварительного описания типа:
Var M: record
case {вариантная часть}
byte of {тип констант для идентификации вариантов}
0: (by: array [0..3] of byte); {массив из 4 байт}
1: (wo: array [0..1] of word); {массив из 2 слов}
2: (lo: longint); {переменная длиной 4 байта}
end;...
§ с предварительным объявлением типа:
Туре
Figure = (Square, Triangle, Circle); {перечисляемый тип}
Paramf = record {тип - запись с вариантами}
X,Y: real; {фиксированные поля}
case {вариантная часть}
Fig: Figure of { переменная и тип идентифицирующих констант}
Square: (Side: real);
Triangle: (Stdel, Side2, Side3: real);
Circle: (Radius: real);
end;
Var Param: Paramf; {объявление переменной}
Конкретное значение переменной типа «запись с вариантами» присваивается точно так же, как и обычной записи: вводом с клавиатуры, с помощью литеральной константы и с помощью типизированной константы. Однако при объявлении инициализированной переменной для вариантной части задается только один вариант.
Например, пусть запись должна содержать либо данные о человеке, либо о корабле (так, Георгий Седов - это и имя человека, и название корабля). Для этого опишем следующую запись с вариантами
Туре
Forma = record {запись места прописки человека и корабля}
case {вариантная часть}
boolean of {тин констант, идентифицирующие вариант}
{вариант для человека}
True: (BirthPlace: string[40]; {место проживания}
{вариант для корабли}
False: (Country: string[20]; {страна}
EntryPort: strtng[20]; {порт}
EntryDate: array [l..3] of word; {дата}
Count: word) {водоизмещение}
end;...
Типизированные константы для задания исходных данных двух записей: Object2 - запись о человеке, Object1 - запись о корабле определяются так;
Const
Object1: forma = (Country: 'Польша';
EntryPort: 'Ленинград';
EntryDate: (l6,3,89);
Count:12);
Object2: Forma = (Birthplace: 'Москва'); ...
Следует отметить, что идентификаторы полей во всех вариантах должны быть различны, а также не совпадать с именами полей фиксированной части. Для некоторых значений констант, идентифицирующих вариант поля в вариантной части записи могут отсутствовать, тогда после двоеточия можно поместить пустой список «( )».
Кроме того, при использовании записей с вариантами необходимо учитывать некоторые особенности:
Для размещения переменной типа запись всегда oотводится фиксированный объем памяти в соответствии с объемом, занимаемым самым большим из вариантов, т. е. различные варианты размещаются на одном участке памяти, как бы «накладываясь» друг на друга.
Транслятор языка не содержит никаких средств контроля корректной обработки вариантных записей. Это означает, что в любое время возможен доступ ко всем нолям во всех вариантах.
За соответствием хранимой информации и вариантом доступа к ней должен следить сам программист. Однако именно эта особенность записей с вариантами может использоваться для неявного преобразования типов данных.
Поскольку различные варианты ссылаются на один участок памяти, как бы «накладываясь» друг на друга, можно обращаться к содержимому памяти поочередно, то как к переменной одного типа, то как к переменной другого. Например:
Туре Perem = record {запись с вариантами}
case byte of
0: Wo: word; {переменная типа word}
1: Lo: longint; {переменная тина longint}
2: Re: real; {переменная типа real}
end;
Var C: Perem;
Begin...
C.Lo:=0; {очищаем область}
C.Wo:=10; {в вариантное поле по шаблону целого без знака записываем число 10}
WriteLn(C.Lo:l0);... {печатается содержимое вариантного поля по шаблону длинного целого}
В этом примере под поля будет выделено 6 байт памяти в соответствии с самым длинным типом во внутреннем представлении. Пользователь может работать с этим полем по любому из шаблонов, используя идентификаторы соответствующих полей записи.
Лекция 16.Множественный тип данных(2 часа)
Дата добавления: 2015-12-01; просмотров: 1015;