Комбинированный тип данных (записи)
Описание
Разбор на примере
При работе с массивами основное ограничение заключается в том, что каждый элемент должен иметь один и тот же тип. Но при решении многих задач возникает необходимость хранить и обрабатывать совокупности данных различного типа.
Пример
Для каждого из 25 учеников класса известны фамилия и оценка (в баллах) по пяти дисциплинам. Требуется вычислить среднюю оценку каждого ученика и выбрать человека, имеющего максимальный средний балл.
В данном случае фамилия может быть представлена строкой из 15 символов, оценка - это целое число, а средний балл должен быть представлен вещественным (действительным) числом. В Паскале для описания комбинаций объектов разных типов используются записи.
Запись - это структурированный тип, содержащий набор объектов разных типов. Составляющие запись объекты называются ее полями. В записи каждое поле имеет свое собственное имя. Чтобы описать запись, необходимо указать ее имя, имена объектов, составляющих запись и их типы. Общий вид такой:
Type
"имя записи" = Record
"поле 1" : "тип 1";
"поле 2" : "тип 2";
...
"поле n" : "тип n"
End;
Данные для решения рассматриваемой задачи можно описать как запись следующим образом:
Type
pupil = Record
fam: String[15]; {поле фамилии ученика}
b1, b2, b3, b4, b5 : 2...5; {поля баллов по дисциплинам}
sb : Real {поле среднего балла}
End;;
Запись
Переменная типа puple будет иметь смысл структуры, содержащий информацию, характеризующую одного ученика. Организация этой структуры показана на рис.1.
Чтобы хранить в памяти ЭВМ информацию о всех 25 учениках класса, необходимо ввести массив klass, представляющий массив записей:
Var klass : Array[1.25] Of pupil;
Примечания
Доступ к полям записи
Его можно осуществить двумя способами.
For i:
= 1 To 25 Do
Begin
Readln(klass[i].fam);
Readln(klass[i].b1);
Readln(klass[i].b2);
Readln(klass[i].b3);
Readln(klass[i].b4);
Readln(klass[i].b5);
End;
With <имя записи> Do <оператор>.
Внутри оператора к компонентам записи можно обращаться только с помощью имени соответствующего поля.
Пример
For i
: = 1 To 25 Do
With klass [i] Do
Begin
Readln (fam);
ReadLn (b1,b2,b3,b4,b5);
End;
Программа для решения рассматриваемой задачи может быть записана в следующем виде:
Program Example_54;
Type
pupil
= Record
fam : String[15];
b1, b2, b3, b4, b5 :2..5;
sb : Real;
End;
Var klass : Array[1..25] Of pupil;
p : pupil;
i, m : Integer;
sbmax : Real;
Begin
{ввод исходных данных}
For i:=1 To 25 Do
With klass[i] Do
Begin
Writeln ('Введите фамилию и пять оценок');
Readln(fam);
ReadLn(b1,b2,b3,b4,b5);
End;
For i:=1 To m Do
With klass[i] Do sb:=(b1+b2+b3+b4+b5)/5; {поиск максимального среднего балла}
sbmax:=0;
For i:=1 To m Do
If klass[i].sb>=sbmax Then sbmax:=klass[i].sb; {печать результатов}
For i:=1 To m Do
If klass[i].sb=sbmax Then
With klass[i] Do Writeln(fam:20,'-',sb:6:3);
Readln;
End.
Пример
Определить дату завтрашнего дня.
Решение
Чтобы определить дату завтрашнего дня, надо знать не только дату сегодняшнего дня, но и количество дней данного месяца (так как если это последний день месяца, то завтра будет первый день следующего), кроме того, надо знать, какой год - високосный или нет (от этого зависит количество дней февраля).
Пусть дата вводится следующим образом:
1 2 1997
Первая цифра - это число, вторая - месяц, третья - год. Тогда можно описать запись даты таким образом:
Type
year = 1500..2000;
month = 1..12;
day = 1..31;
data =
Record
y : year;
m : month;
d : day;
End;
Заметим, что:
|
Если это не последний день месяца, то завтра будет этот же год, этот же месяц, а число увеличится на 1. |
|
Если это последний день месяца, то:
|
Program Example_55;
Type year = 1500..2000;
month = 1..12;
day = 1..31;
data = Record
y : year;
m : month;
d : day;
End;
Var dat, next : data; {dat - переменная для сегодняшней даты, next - переменная
для определения даты завтрашнего дня}
Function Leap(yy: year): Boolean;
{функция, определяющая високосный год или нет}
Begin
{год называется високосным, если его номер делится на 4, но если это год
столетия, то номер столетия не делится на 4, то есть не делится на 400}
Leap: = (yy Mod 4 = 0) And ( yy Mod 400 <> 0);
End;
Function Dmonth (mm: month; yy: year): day;
{функция определения количества дней данного месяца в данном году}
Begin
Case mm Of
1, 3, 5, 7, 10, 12 : Dmonth := 31;
4, 6, 9, 11 : Dmonth := 30;
If Leap (yy) Then Dmonth := 29
Else Dmonth := 28;
End;
End;
Procedure Tomorrow(td: data; Var nd: data);
{процедура определения завтрашней даты}
Begin
If td.d<> Dmonth(td.m,td.y) {если это не последний день месяца}
Then With nd Do Begin
d := td.d + 1;
m := td.m;
y := td.y;
End {если это последний день месяца}
Else {если это декабрь}
If td.m = 12 Then
With nd Do Begin
d := 1;
m := 1;
y := td.y + 1;
End {если это не декабрь}
Else
With nd Do Begin
d := 1;
m := td.m + 1;
y := td.y;
End;
End;
Begin
Writeln('Введите сегодняшнее число,месяц и год');
Readln( dat.d,dat.m,dat.y);
Tomorrow(dat,next);
Writeln('Завтра будет ');
Writeln(next.d,'.',next.m,'.',next.y);
Readln;
End.
Решение задач
Type
time = Record
h : 0..23;
m, s : 0..59
End;
Описать:
Считая, что в таблице записи имеют различные ключи, описать: