При работе с массивами основное
ограничение заключается в том, что каждый
элемент должен иметь один и тот же тип. Но
при решении многих задач возникает
необходимость хранить и обрабатывать
совокупности данных различного типа.
Пример
Для каждого из 25 учеников класса известны
фамилия и оценка (в баллах) по пяти
дисциплинам. Требуется вычислить среднюю
оценку каждого ученика и выбрать человека,
имеющего максимальный средний балл.
В данном случае фамилия может быть
представлена строкой из 15 символов, оценка -
это целое число, а средний балл должен быть
представлен вещественным (действительным)
числом. В Паскале для описания комбинаций
объектов разных типов используются записи.
Запись - это структурированный тип,
содержащий набор объектов разных типов.
Составляющие запись объекты называются ее
полями. В записи каждое поле имеет свое
собственное имя. Чтобы описать запись,
необходимо указать ее имя, имена объектов,
составляющих запись и их типы. Общий вид
такой:
Данные для решения рассматриваемой
задачи можно описать как запись следующим
образом:
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;
Примечания
Имена полей, составляющих запись, не
должны повторяться.
Каждое поле записи может иметь любой тип
(кроме файлового),в частности, оно может
быть снова записью.
Доступ к полям записи
Его можно осуществить двумя способами.
Указанием имени переменной и имени поля.
Например, klass[2].fam, klass[3].sb, klass[1].b4. Поэтому
ввод фамилий и оценок учащихся, то есть
элементов массива klass, можно задать так:
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.
Решение задач
Написать программу, определяющую:
дату следующего (предыдущего) дня;
дату, которая наступит через mдней;
дату, которая была за m дней до
сегодняшнего дня;
количество суток, прошедших от даты t1
до t2;
день недели, выпадающий на дату t1,
если известно, что в первый день нашей
эры был понедельник.
Дано время, описанное следующим образом:
Type time = Record
h : 0..23;
m, s : 0..59 End;
Описать:
логическую функцию для проверки,
предшествует ли время t1 времени t2
(в рамках суток);
процедуру, присваивающую параметру t1
время, на 1 секунду большее времени t
(учесть смену суток).
Const n = 300; Type MyRecord = Record
Key : Integer;
Name : String; End; Var Table = Array[1..n] Of MyRecord;
Считая, что в таблице записи имеют
различные ключи, описать:
процедуру, упорядочивающую записи
таблицы по убыванию значений поля Key;
логическую функцию поиск (Т,К,Н),
определяющую, есть ли в таблице Т (все
записи которой уже упорядочены по
возрастанию значений поля Key) запись со
значением поля Key, равным К, и, если есть,
присваивающую ее номер параметру Н.
Дан массив, содержащий информацию об
учениках некоторой школы.
Заполнить второй массив данными об
учениках только девятых классов;
Выяснить, на сколько человек в восьмых
классах больше, чем в девятых.
Багаж пассажира характеризуется
количеством вещей и общим весом вещей.
Дан массив, содержащий сведения о багаже
нескольких пассажиров. Сведения о багаже
каждого пассажира представляют собой
запись с двумя полями: одно поле целого
типа (количество вещей) и другое -
действительное (вес в килограммах).
Найти багаж, средний вес одной вещи в
котором отличается не более чем на 0,3 кг
от общего среднего веса одной вещи;
Найти число пассажиров, имеющих более
двух вещей и число пассажиров,
количество вещей которых превосходит
среднее число вещей;
Выяснить, имеется ли пассажир, багаж
которого состоит из одной вещи весом
менее 30 кг