Записи с фиксированными частями

Записи с фиксированными частями называются так, потому, что в различных ситуациях имеют одинаковую структуру.

Например, запись "Личная карточка студента" может быть описана с помощью записи с фиксированными частями:

Type

student = record

family : string[20];

name : string[10];

patronymic : string[15];

year_birthday : integer;

number_of_group : integer; // Номер группы

Predmet1 : byte; // МатАнализ

Predmet2 : byte; // ИнжГрафика

Predmet3 : byte; // Химия

Predmet4 : byte; // Информатика

end;

Если поля несут одинаковую смысловую нагрузку, то их целесообразно объединить в отдельную структуру типа record.

Пример 11.1.

type student =record

family :string[20];

family : string[20];

name : string[10];

patronymic : string[15];

year_birthday : integer;

number_of_group : integer; // Номер групп

valuation =record // Оценки

Predmet1 : byte; // МатАнализ

Predmet2 : byte; // ИнжГрафика

Predmet3 : byte; // Химия

Predmet4 : byte; // Информатика

end;

end;

group = array[1..25] of student;

Var

group1, group2 : group;

Пример 11.2.

Type

valuation =record // Оценки

Predmet1 : byte; // МатАнализ

Predmet2 : byte; // ИнжГрафика

Predmet3 : byte; // Химия

Predmet4 : byte; // Информатика

end;

student = record

family : string[20];

name : string[10];

patronymic : string[15];

year_birthday : integer;

number_of_group : integer;

// Оценки за прошедший семестр

valuation_of_last_half_year : valuation;

end;

group = array[1..25] of student;

Var

group1, group2 : group;

Переменные типа record могут участвовать в операторах присваивания, но никакие операции над ними не допускаются. Арифметические или какие-либо другие операции могут выполняться только над отдельными полями записи.

К каждому из компонентов записи можно получить доступ, если использовать составное имя, то есть указать имя переменной, затем точку и имя поля.

Например, Client.name := “Mary”; или

Group1[1].family := “Ivanov”;

Для вложенных полей приходиться продолжать уточнения.

Например,

Group2[2]. Valuation_of_last_half_year.Predmet1 := 5;

11.2. Оператор WITH…DO

При совместной обработке нескольких полей записи можно воспользоваться оператором WITH…DO:

WITH <ПЕРЕМЕННАЯ> DO <ОПЕРАТОР>;

Здесь, WITH, DO – ключевые слова (с, делать);

<переменная> - имя переменной типа запись, за которым, возможно, следует список вложенных полей;

<оператор> - любой оператор TP.

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

Например, вместо операторов

Client.name := “Mary”;

Client.family := “Ivanov”;

Client.year_birthday := 1986;

можем записать:

With Client do

Begin

name := “Mary”;

family := “Ivanov”;

year_birthday := 1986;

End;

Или, например, для заполнения массива, элементами которого являются записи:

For i := 1to ndo

Begin

With Group[i] do

Begin

Writeln (name);

Writeln (family);

Writeln (year_birthday);

With Valuation_of_last_half_year do

Begin

Writeln (Predmet1);

Writeln (Predmet2);

Writeln (Predmet3);

Writeln (Predmet4);

End;

End;

End;

Использование оператора WITH…DO даёт существенную экономию в размере программы.

Вариантные записи

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

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

Описание типа <запись с вариантами> имеет следующий тип:

Type

Rec = record

{Описания фиксированных частей}

v1, v2 : Integer;

{Описание полей вариантной части}

case n : Word of

0 : (<Список полей – описаний переменных>);

1 : (<Список полей – описаний переменных>);

7 : (<Список полей – описаний переменных>);

end;

Здесь, описание включает вариантную часть, в которой используется оператор CASE. Описание завершается зарезервированным словом END. В качестве селектора используется идентификатор типа (n : Word). Переменная часть должна следовать после фиксированной части, если таковая имеется.

Например,

Type

Valuation1_of_last_half_year = record

Predmet1 : byte; // МатАнализ

Predmet2 : byte; // ИнжГрафика

Predmet3 : byte; // Химия

Predmet4 : byte; // Информатика

End;

Valuation2_of_last_half_year = record

Predmet5 : byte;

Predmet6 : byte;

Predmet7 : byte;

Predmet8 : byte;

End;

Student = record

{фиксированная часть записи}

family : string[20];

name : string[10];

patronymic : string[15];

year_birthday : integer;

number_of_group : integer; // Номер групп

{вариантная часть записи }

case half_year : byte of

1 : (val1 : Valuation1_of_last_half_year); { Оценки за 1-ый семестр}

2 : (val2 : Valuation2_of_last_half_year); { Оценки за 2-ой семестр}

end;

group = array[1..25] of student;

Var

group1, group2 : group;

Здесь, вариантная часть записи включает две части:

· обычная фиксированная часть;

· вариантная часть, состоящая из поля признака (поля тела).

Заполнение записи такого вида:

Fori := 1tondo begin

With group1[i] do

Begin

{Заполнение фиксированной части}

…..

{Заполнение вариантной части}

half_year := 1;

With val1 do

Begin

Predmet1 := 5;

Predmet2 := 2;

Predmet3 := 3;

Predmet4 := 4;

End;

End; End;

Оператор FillChar(Group1[i], SizeOf(Group[i]),’’); заполняет пробелами поля записи и используется для того, чтобы новые данные каждый раз помещались на чистое место.

Если этот оператор не использован, может возникнуть ситуация, когда в ответ на запрос о вводе строки в некоторое поле Вы нажмёте клавишу [Enter], а в поле останется старое содержимое. Именно это помогает избежать процедура FillChar().

Задача 11.1.Необходимо организовать хранение информации о студентах некоторого вуза так, чтобы по каждому студенту фиксировались 4 основные характеристики: имя, год рождения, адрес и успеваемость. Распечатать список студентов, фамилии которых начинаются с буквы «Г», и их оценки за всё время обучения.

Листинг программы

PROGRAM LAB10_SEVEN; {Запись в файл}

USES CRT;

TYPE NAME1 = RECORD N : STRING[10]; {имя студента}

FAM : STRING[10]; {фамилия студента}

END;

STR_ADD1 = RECORD HOUSENUM : INTEGER; {номер дома}

STREET : STRING[10]; {название улицы}

END;

ADDRESS1 = RECORD STR_ADD : STR_ADD1;

CITY : STRING[10]; {название города}

STATE : STRING[15]; {название страны}

ZIP : INTEGER; {индекс города}

END;

SUBJECT1 = RECORD

SUB : ARRAY[1..10] OF STRING[10]; {массив предметов}

BALL : ARRAY[1..10] OF INTEGER; {массив баллов}

M1 : INTEGER; {количество предметов}

END;

TEACH1 = RECORD

YEAR : STRING[4]; {год поступления в вуз}

SUBJECT : SUBJECT1; {предметы}

MIDDLE : REAL; {среднее значение}

END;

STUDENT1 = ARRAY[1..25] OF RECORD

NAME : NAME1;

YEARB : STRING[4];

ADDRESS : ADDRESS1;

TEACH : TEACH1;

END;

LIBFILE = FILE OF STUDENT1;

VAR S: STUDENT1;

G1 : STUDENT1;

F : LIBFILE;

N, I, J : INTEGER;

PROCEDURE ENTER;

VAR P : REAL;

BEGIN

ASSIGN (F,'E:\7\GFILE.DAT');

REWRITE (F);

WRITELN ('Введите количество студентов в группе <= 25');

READLN (N);

FOR I := 1 TO N DO BEGIN

WITH S[I] DO BEGIN

WITH NAME DO BEGIN

TEXTMODE(CO80); TEXTCOLOR(LIGHTBLUE);

WRITE ('Введите фамилию '); TEXTCOLOR(MAGENTA); GOTOXY(35,1);

READLN (FAM); TEXTCOLOR(LIGHTBLUE);

WRITE ('Введите имя '); TEXTCOLOR(MAGENTA); GOTOXY(35,2);

READLN (N); TEXTCOLOR(LIGHTBLUE);

END;

WRITE ('Введите год рождения '); TEXTCOLOR(MAGENTA); GOTOXY(35,3);

READLN (YEARB); TEXTCOLOR(LIGHTBLUE);

WITH ADDRESS DO BEGIN

WITH STR_ADD DO BEGIN

WRITE ('Введите номер дома '); TEXTCOLOR(MAGENTA); GOTOXY(35,4);

READLN (HOUSENUM); TEXTCOLOR(LIGHTBLUE);

WRITE ('Введите название улицы ');TEXTCOLOR(MAGENTA); GOTOXY(35,5);

READLN (STREET); TEXTCOLOR(LIGHTBLUE);

END;

WRITE ('Введите название города ');TEXTCOLOR(MAGENTA); GOTOXY(35,6);

READLN (CITY); TEXTCOLOR(LIGHTBLUE);

WRITE ('Введите название штата ');TEXTCOLOR(MAGENTA); GOTOXY(35,7);

READLN (STATE); TEXTCOLOR(LIGHTBLUE);

WRITE ('Введите номер индекса '); TEXTCOLOR(MAGENTA); GOTOXY(35,8);

READLN (ZIP); TEXTCOLOR(LIGHTBLUE);

END;

WITH TEACH DO BEGIN

WRITE ('Введите год поступления в ВУЗ '); TEXTCOLOR(MAGENTA); GOTOXY(35,9);

READLN (YEAR); TEXTCOLOR(LIGHTBLUE);

WITH SUBJECT DO BEGIN

WRITE ('Введите количество предметов '); TEXTCOLOR(MAGENTA); GOTOXY(35,10);

READLN (M1);

P := 0;

FOR J := 1 TO M1 DO BEGIN

TEXTCOLOR(LIGHTBLUE); GOTOXY (1,11); CLREOL;

WRITE ('Введите название предмета ');

TEXTCOLOR (MAGENTA); GOTOXY(40,11);

READLN (SUB[J]);

TEXTCOLOR(LIGHTBLUE); GOTOXY (1,12); CLREOL;

WRITE ('Введите результат последней сессии ');

TEXTCOLOR (MAGENTA); GOTOXY(40,12);

READLN (BALL[J]);

P := P + BALL[J];

END;

P := P / M1;

MIDDLE := P;

END; END; END;

WRITELN; END;

WRITE(F,S);

CLOSE (F);

TEXTCOLOR(LIGHTGRAY);

TEXTMODE(CO80+8*8);

END;

PROCEDURE EX;

VAR K, L, H : INTEGER;

BEGIN

H := 15;

RESET (F);

IF IORESULT <> 0 THEN BEGIN CLOSE (F); HALT; END

ELSE BEGIN WHILE NOT EOF (F) DO BEGIN

READ (F,G1);

END; END;

L := 10;

TEXTCOLOR (LIGHTBLUE); GOTOXY (1,1);

WRITELN ('Фамилия ');

WRITELN ('Имя');

WRITELN ('Дата рождения: ');

FOR I := 1 TO N DO BEGIN

WITH G1[I] DO BEGIN

IF NAME.FAM[1] = 'Ѓ' THEN BEGIN

WITH NAME DO BEGIN

TEXTCOLOR (MAGENTA);

GOTOXY (H + L,1); WRITELN (FAM);

GOTOXY (H + L,2); WRITELN (N);

END;

GOTOXY (H + L,3); WRITELN (YEARB);

L := L + 20;

WRITELN; END; END; END;

READKEY;

CLOSE (F);

END;

BEGIN

CLRSCR;

ENTER;

EX;

END.

Вопросы для самопроверки

1. Дайте определение записи?

2. Каков формат описания переменной типа запись в разделе описания переменных?

3. Где описывается поле записи?

4. Как называется запись, объявленная в разделе Var?

5. Каков формат описания переменной типа запись в разделе Var, при наличии вложенной записи?

6. В чём состоит отличие в описании записи, объявленной в разделе Type?

7. Как описать тип записи в разделе описания новых типов, при наличии вложенной записи?

8. Какой подход используют при описании переменной типа запись в разделе Var, при наличии нового типа записи?

9. Какой используют способ доступа к полям записи?

10. Как можно осуществить доступ к полям вложенной записи?

11. В чём состоит преимущество использования оператора With..do?

Лабораторная работа №11

Наши рекомендации