Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСНОВЫ АЛГОРИТМИЗАЦИИ.doc
Скачиваний:
14
Добавлен:
16.08.2019
Размер:
1.8 Mб
Скачать

11.2. Оператор with…do

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

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 := 1 to n do

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 даёт существенную экономию в размере программы.

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

Особой разновидностью записей являются записи с вариантами, которые объявляются с использованием зарезервированного слова 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;

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

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

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

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

For i := 1 to n do 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.