Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
D.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
109.06 Кб
Скачать

3.4 Оператор присоединения

Используя "точечную" нотацию при обращении к полям записи, мы выписывали всю цепочку имен, начиная с высшего уровня до имени конкретного объекта (или поля), к которому шло обращение. Оператор присоединения позволяет упростить обращение к полю записи. Имя записи выносится в заголовок оператора присоединения, а в теле оператора используются только имена полей записи.

Формат оператора присоединения:

with <имя записи-переменной> do

<оператор>;

Если после do стоят несколько операторов (составной оператор), то их заключают в операторные скобки, и оператор присоединения имеет формат:

with <имя записи-переменной> do

begin

<оператор 1>;

<оператор 2>;

. . . . .

<оператор n>;

end;

Имя записи-перменной, указанное в заголовке оператора присоединения, автоматически присоединяется ко всем именам полей, упомянутым в теле оператора with.

Пример записи оператора присоединения:

а) для структуры 1-го типа:

. . . . . .

with STUDENT do

begin

Read(FIO); {вводим фамилию студента: Иванов И.И.},

Read(STIP); {вводим стипендию студента 125},

K := 5;

N_ZACH := 987671;

GR := 56;

Write(FIO, '':3, K, '':3, GR)

end;

. . . .

б) для структуры 2-го типа (вложенные записи):

. . . .

with STUDENT do

begin

Read(GRUP.FIO); {вводим фамилию студента: Федорова А.А.},

Read(GRUP.STIP); {вводим стипендию студента: 83},

K:= 5;

GRUP.N_ZACH := 987650;

GRUP.GR := 53;

Write(GRUP.FIO, '':3, K, '':3, GRUP.GR)

end;

. . . .

В одном заголовке оператора with можно задать не одно имя записи, а целый список имен различных записей (от высшего уровня к низшему), разделенных запятой.

. . . .

with STUDENT,GRUP do

begin

Read(FIO); {вводим фамилию студента: Петрова Н.Н.},

Read(STIP); {вводим стипендию студента: 105},

K := 5;

N_ZACH := 987654;

GR := 55;

Write(FIO, '':3, K, '':3, GR)

end;

. . . .

Приведенная форма записи оператора with эквивалентна следующей:

. . . .

with STUDENT do

with GRUP do

begin

Read(FIO); {вводим фамилию студента: Петрова Н.Н.},

Read(STIP); {вводим стипендию студента: 105},

K:=5;

N_ZACH := 987654;

GR := 55;

Write(FIO, '':3, K, '':3, GR)

end;

. . . .

Если использовать оператор with в форме: . . . .

with STUDENT.GRUP do

begin

Read(FIO); {вводим фамилию студента: Петрова Н.Н.},

Read(STIP); {вводим стипендию студента: 105},

K:= 5;

N_ZACH := 987654;

GR := 55;

Write(FIO, '':3, K, '':3, GR)

end;

. . . .

то программа работать не будет, так как при таком использовании оператора with выполняется работа только с полями записи GRUP (см. также описание «точечной» нотации. Поэтому оператор K:= 5; следует исключить ( K – поле записи STUDENT, но не GRUP) и в операторе Write удалить фрагмент (K, ‘’:3,).

Пример 1. Дана сводная ведомость результатов экзаменов группы в сессию:

Иванов Н.П. 5 4 3 4

Петров А.П. 5 4 5 3

Сидорова Е.Е. 3 3 4 3

. . . .

Найти средний балл группы и напечатать список студентов, имеющих средний балл выше среднего по группе.

План решения.

1. Пусть в группе n студентов. Опишем массив ST, состоящий из записей, содержащих данные по каждому студенту.

2. Введем этот массив, одновременно вычисляя средний балл каждого студента и накапливая сумму S - сумму средних баллов.

3. Находим средний балл по группе: S=S/n.

4. Печатаем список студентов, которые учатся хорошо, т.е. имеют средний балл выше среднего по группе.

program ZAPISI_1;

uses crt;

const n=25;

type

STUDENT=record

fio:string[20];

bal:array[1..4] of 2..5;

sr_bal:real

end;

var

ST:array[1..n] of STUDENT;

i,j:integer; S:real;

begin clrscr; S:=0;

for i:=1 to n do

with ST[i] do

begin Write('Введите фамилию студента: ');

Readln(fio); sr_bal:=0;

Writeln('Введите оценки:');

for j:=1 to 4 do

begin read(bal[j]);

sr_bal:=sr_bal+bal[j]

end;

Readln;

sr_bal:=sr_bal/4;

S:=S+sr_bal

end;

S:=S/n;

Writeln('Средний балл группы равен ',S:4:2);

Writeln;

Writeln('Список студентов, которые учатся хорошо:');

for i:=1 to n do

if ST[i].sr_bal>S then Writeln(ST[i].fio,'':4,ST[i].sr_bal:4:2)

end.

Для тестирования зададим в разделе const n=3.

Исполнение программы:

Введите фамилию студента:

Иванов Н.П.

Введите оценки:

5 4 3 4

Введите фамилию студента:

Петров А.П.

Введите оценки:

5 4 5 3

Введите фамилию студента:

Сидорова Е.Е.

Введите оценки:

3 3 4 3

Средний балл группы равен 3.83

Список студентов, которые учатся хорошо

Иванов Н.П. 4

Петров А.П. 4.25

Пример 2. В справочной аэропорта хранится расписание полетов на следующие сутки. Для каждого рейса указаны его номер, тип самолета, пункт назначения, время вылета, время в полете. Определить номера рейсов, время вылета и типы самолетов, прибывающих в заданный пункт назначения до 12 часов.

program ZAPISI_2;

uses crt;

const n=30; { n - общее число рейсов в расписании}

type

time_rec= record

chas:0..24;

min:0..60

end;

data_rec=record

day:1..31;

mec:1..13

end;

info_samolet=record

punkt_naznach:string[15];

nomer_reisa:integer;

tip_samoleta:string[10];

data_vileta:data_rec;

time_vileta:time_rec;

time_poleta:time_rec;

end;

var

raspisanie:array [1..n] of info_samolet;

gorod:string[15];

i,k:integer;

time:time_rec;

begin clrscr;

Writeln('':10,'РАСПИСАНИЕ РЕЙСОВ');

for i:=1 to n do

with raspisanie[i] do

begin

Writeln('Введите ');

Write('пункт назначения:','':14);

Readln(punkt_naznach);

Write('номер рейса:','':19); Readln(nomer_reisa);

Write('тип самолета:','':18); Readln(tip_samoleta);

Write('дата вылета /день месяц/:','':6);

Readln(data_vileta.day, data_vileta.mec);

Write('время вылета /час мин/:','':8);

with time_vileta do Readln(chas,min);

Write('время полета /час мин/:','':8);

with time_poleta do Readln(chas,min);

end;

Writeln;

Write('Введите пункт прибытия:','':8); Readln(gorod);

for i:=1 to n do

with raspisanie[i] do

begin

k:=time_vileta.chas+time_poleta.chas;

if (time_vileta.min+time_poleta.min) >=60 then k:=k+1;

if (k mod 24 <12) and (punkt_naznach=gorod) then

begin

Writeln('':11, 'номер рейса:', '':8, nomer_reisa);

Writeln('':10,'тип самолета:','':8,tip_samoleta);

with time_vileta do

Writeln('':10,'время вылета:' , '':8, chas, 'час ':3, min, 'мин');

end

end

end.

Для тестирования зададим в разделе const n=3.

Исполнение программы:

РАСПИСАНИЕ РЕЙСОВ

Введите

пункт назначения: Москва

номер рейса: 123

тип самолета: ТУ-124

дата вылета /день месяц/: 03 02

время вылета /час мин/: 02 10

время полета /час мин/: 09 59

Введите

пункт назначения: Санкт-Петербург

номер рейса: 345

тип самолета: ИЛ-16

дата вылета /день месяц/: 03 02

время вылета /час мин/: 08 45

время полета /час мин/: 02 30

Введите

пункт назначения: Москва

номер рейса: 127

тип самолета: АН-24

дата вылета /день месяц/: 03 02

время вылета /час мин/: 05 45

время полета /час мин/: 04 50

Введите пункт прибытия: Москва

номер рейса: 127

тип самолета: АН-24

время вылета: 05 45

Замечание. Если данные time_vileta и time_poleta опишем как поля записи data_rec, то в программе изменится:

- описание записей data_rec и info_samolet;

- запись оператора присоединения и обращение к полям day, mec.

program ZAPISI_2_1;

uses crt;

const n=30; { n - общее число рейсов в расписании}

type

time_rec= record

chas:0..24;

min:0..60

end;

data_rec=record

day:1..31;

mec:1..13;

time_vileta:time_rec;

time_poleta:time_rec;

end;

info_samolet=record

punkt_naznach:string[15];

nomer_reisa:integer;

tip_samoleta:string[10];

data_vileta:data_rec;

end;

var

. . .

begin clrscr;

Writeln('РАСПИСАНИЕ РЕЙСОВ');

for i:=1 to n do

with raspisanie[i], data_vileta do

begin

. . .

Write('дата вылета /день месяц/:','':6);

Readln(day, mec);

. . .

end;

. . . . . .

for i:=1 to n do

with raspisanie[i], data_vileta do

begin k:=time_vileta.chas+time_poleta.chas;

if (time_vileta.min+time_poleta.min) >=60 then k:=k+1;

. . .

end

end.

Возможны и другие варианты оформления программы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]