Обращение к отдельным компонентам записи при помощи составных имен приводит к удлинению текста программы и к ее излишней громоздкости (особенно при использовании идентификаторов из 5 и более символов). Для устранения этого неудобства в языке Object Pascal используется оператор присоединения WITH, который позволяет осуществлять доступ к компонентам записи таким образом, как если бы они были обычными переменными, т.е отпадает необходимость указывать при обращении к отдельному полю записи кроме его собственного идентификатора еще и идентификатор записи.
Формат оператора присоединения:
WITH < переменная типа запись > DO < оператор >;
Внутри оператора WITH можно обращаться к компонентам записи по именам полей без указания перед идентификаторами поля имени переменной, определяющей запись. Так, нахождение среднего балла у группы студентов из предыдущего примера можно осуществить следующим образом:
VAR
S:Real;
…
FOR I := 1 TO 30 DO
WITH GRUPPA [I] DO
S:=S+SB;
S:=S/30;
Язык Object Pascal допускает вложение записей друг в друга (т.е. поле в записи может в свою очередь быть тоже записью и т.д.), соответственно и оператор WITH тоже может быть вложенным:
WITH R1 DO
WITH R2 DO
WITH R3 DO
…
что эквивалентно записи
WITH R1R2R3 DO …
Замечание. Так как в языке Object Pascal нет специальных средств для описания комплексных чисел, то для решения этой задачи могут быть использованы записи. В этом случае действительная и мнимая части комплексного числа представляются в виде полей записи:
TYPE
COMPLEX = RECORD
DEYSTV : REAL; // действительная часть числа
MNIM: REAL; //мнимая часть числа
END;
VAR
A,B,C1,D2:COMPLEX;
BEGIN
A.DEYSTV := 73.8;
A.MNIM := 43.5;
…
Все записи, рассмотренные ранее, имеют строго определенную структуру, что в некоторых случаях ограничивает возможности их применения. Для исключения этого недостатка в языке Object Pascal есть возможность задавать тип записи, содержащей произвольное число вариантов структуры. Такие записи – записи с вариантами.
ЗАПИСИ С ВАРИАНТАМИ – состоят из необязательной фиксированной общей части (не отличается от рассмотренных выше записей) и вариантной части, отличающейся в различных записях.
Вариантная часть формируется с помощью оператора CASE, который задает особое поле записи – поле признака, определяющее, какой из вариантов в данный момент будет активизирован. Значением признака в каждый текущий момент выполнения программы должна быть одна из расположенных далее констант. Константа, служащая признаком, задает вариант записи и называется константой выбора.
Формат объявления записи с вариантами:
TYPE
ZAP = RECORD
CASE <поле признака >: <имя типа > OF
<константа выбора 1 > : (поле, …: тип);
< константа выбора 2 >: (поле, …: тип);
…
…
END;
Компоненты каждого варианта (идентификаторы полей и их типы) заключаются в круглые скобки, например:
TYPE
POL = (M, J);
PERSON = RECORD
Fam : STRING [35];
GodRojd: 1970..2000;
mj: POL;
CASE mj: POL OF
M: (Voen: BOOLEAN; Spec: STRING [30]);
J: (Zamuj: BOOLEAN; Childs: BYTE)
END;
VAR
ST1, ST2, ST3, ST4: PERSON;
Поля Voen и Spec используются только в том случае, если значение поля mj равно M, поля Zamuj и Child – при значении поля mj – J.
Замечание:
- Все имена полей должны отличаться друг от друга, даже если они встречаются в разных вариантах;
- Запись может иметь только одну вариантную часть, причем вариантная часть должна размещаться в конце записи;
- Если поле, соответствующее какой-либо метке, является пустым, то оно записывается так < метка > : ( ) ;
ПРИМЕР РЕШЕНИЯ ЗАДАЧИ С ИСПОЛЬЗОВАНИЕМ ДАННЫХ ТИПА «ЗАПИСЬ»
Разработать программу для обработки информационного массива данных по группе людей из 30 человек. Для каждого человека указаны фамилия и год рождения, вес, рост. Необходимо вычислить средний вес, возраст, рост и упорядочить группу по возрасту.
Используемые в программе идентификаторы приведены в таблице
Табл.
Обозначения
Тип данных
Примечание
PERSONE
RECORD
Запись сведений о человеке
Fam
STRING [30]
Поле записи PERSONE – фамилия
GodRojd,Ves,Rost
INTEGER
Поля записи PERSONE– год рождения, вес, рост.
SB
REAL
Средний балл
Y
RECORD
Промежуточная запись
TBL
ARRAY [1…30] OF STR
Массив, содержащий записи сведений о студентах группы
J
INTEGER
I
INTEGER
K
INTEGER
M
INTEGER
X
REAL
PR
INTEGER
Переменная для управления повторной работой программы
PROGRAM PRIM2;
USES CRT;
TYPE
STR=RECORD
FAM: STRING [30];
B1,B2,B3,B4,B5: 2..5;
SB: REAL
END;
VAR
TBL: ARRAY [1..25] OF STR;
Y:STR;
I,J,K,M:INTEGER;
X,R:REAL;
PR:BYTE;
BEGIN
CLRSCR;
REPEAT
WRITELN ('Введите число студентов');
READLN (M);
FOR I:= 1 TO M DO
WITH TBL[I] DO
BEGIN
WRITELN('Введите фамилию');
READLN (FAM);
WRITELN('Введите пять оценок студента');
READLN (B1,B2,B3,B4,B5);
END;
FOR I:= 1 TO M DO
WITH TBL[I] DO
SB:= (B1+B2+B3+B4+B5)/5;
FOR I:= 1 TO M DO
BEGIN
K:=1;
X:=TBL[I].SB;
FOR J:=I TO M DO
IF TBL[J].SB >=X THEN
BEGIN
K:=J;
X:=TBL[J].SB;
Y:=TBL[K];
TBL[K]:=TBL[I];
TBL[I]:=Y
END;
END;
WRITELN ('Список студентов');
FOR I:=1 TO M DO
WITH TBL[I] DO
WRITELN (FAM, SB:4:2);
WRITELN ('Обработать еще один список? 1-да 0-нет');