В массиве могут содержаться данные только одного и того же типа, например, все целые числа. Однако иногда существует необходимость держать в переменной несколько данных разного типа. Например, в переменной «человек» держать фамилию, имя, рост, возраст, фотографию и т.д… Но даже если все данные одного типа, они могут иметь разный смысл, по-разному обрабатываться. Например, рост, возраст, количество детей, зарплата… Хранение их в одном массиве под разными номерами не даёт преимуществ перед хранением в отдельных переменных. Приходится помнить, какой номер какому данному соответствует.
Для хранения таких разнородных данных об одном объекте существует специальный вид переменных – запись. Части записи называются полями. Каждое поле имеет имя и содержимое. Например, поле с именем Name имеет содержимое ’Иван’. Имя всей записи от имени отдельного поля отделяется точкой. Например, Man.Name:=’Иван’;.
В разделе var запись можно объявить так:
Однако, это не единственный (и не лучший) способ. Если таких записей в программе несколько, более удобен следующий способ. В разделе type (раньше раздела var) создаётся шаблон (образец) для нужной записи. Затем в разделе var этот шаблон используется как новый тип для объявления переменных:
В последней строчке примера показано объявление массива записей. Такую структуру данных принято называть базой данных (БД). (Но надо помнить, что понятие современной БД гораздо шире, чем просто массив из записей). Можно представить такой массив как таблицу, каждая строка которой – одна запись, а каждый столбец – одно поле:
N
Name
Vozrast
Rost
Ves
Александров А.Б.
Борисов В. Г.
Васильев Д. Е.
Григорьев Ж. З.
Для использования одного данного из БД применяются и квадратные скобки (для указания конкретной записи в массиве) и точка (для указания имени поля). Например:
kl8a[1].name:=’Александров’;
При работе с БД удобно накопленную информацию сохранять в файле. Если использовать текстовый файл, каждое поле нужно будет сохранять отдельно. Более оправдано применение типового файла, так как это позволяет сохранять всю запись как одно целое. Посмотрим, как это делается, на примере:
Написать программу «Справочник рыболова». Она использует базу данных «рыбы» и может дополнять её и искать нужную рыбу. По окончании работы вся накопленная информация сохраняется в файле «рыбы.db» в текущем каталоге. При запуске программы файл базы данных (если он уже создан) загружается в массив, и введённую в прошлом сеансе информацию можно использовать.
program fisher;
type
onefish=record
name,eda:string[15];
dlina:integer;
ves:real;
end;
var
fish:array[1..100] of onefish; {база данных - справочник}
f:file of onefish;
isk:string[15]; {переменная для имени искомой рыбы}
i,n,kz:integer;
found:boolean;
begin
kz:=0; {Если базы нет, количество записей останется =0}{----- Сначала загрузим базу из файла -----}
assign(f,'рыболов.dat');
if fileexists('рыболов.dat') then {файл существует}
begin
reset(f); {открываем его}
while not eof(f) do {цикл до конца файла}
begin
inc(kz); {кол-во записей увеличиваем на 1}
read(f,fish[kz]); {прочтём очередную рыбку}
end;
close(f);
end;
{-----------------------------------------}
repeat {============ Цикл возврата в меню =============}
cls;
writeln(' Режимы работы:');
writeln('-------------------------------------');
writeln('1. Добавить новую рыбу');
writeln('2. Удалить рыбу');
writeln('3. Найти рыбу');
writeln('0. Конец работы со справочником');
writeln('-------------------------------------');
write('Введите номер выбранного вида работы: '); readln(n);
cls;
case n of
0: break;
1: begin {------- добавление новой рыбы --------}
if kz=100 then
writeln('База переполнена!')
else
begin
inc(kz);
write('Введите название рыбы: '); readln(fish[kz].name);
write('Введите средний вес (в кг): '); readln(fish[kz].ves);
write('Введите среднюю длину (в см): '); readln(fish[kz].dlina);
write('Введите любимую наживку: '); readln(fish[kz].eda);
end;
end; {--------------------------------------}
2: begin {------- удаление рыбы --------}
write('Введите название удаляемой рыбы: '); readln(isk);
found:=false; {ещё не находили}
for i:=1 to kz do
if fish[i].name=isk then
begin
found:=true;
for n:=i to kz-1 do {передвинем все следующие записи}
begin {на место стираемой}
fish[n].name := fish[n+1].name;
fish[n].ves := fish[n+1].ves;
fish[n].dlina := fish[n+1].dlina;
fish[n].eda := fish[n+1].eda;
end;
dec(kz); {уменьшим количество занятых записей}
end;
if found then
writeln('Удаление произведено')
else
writeln('Такой рыбы нет в справочнике');
end; {------------------------------}
3: begin {------- поиск рыбы --------}
write('Введите название искомой рыбы: '); readln(isk);
found:=false; {ещё не находили}
for i:=1 to kz do
if fish[i].name=isk then
begin
found:=true;
writeln('Вес: ',fish[i].ves);
writeln('Длина: ',fish[i].dlina);
writeln('Любимая наживка: ',fish[i].eda);
writeln;
end;
if not found then
writeln('Такой рыбы нет в справочнике');
end; {---------------------------}
end;
writeln; writeln; writeln('Нажмите <Enter> для возврата в меню');
readln;
until false; {===========================================}{===== Сохраним в файле =====}
if cancreatefile('рыболов.dat') then {файл создать можно}
begin
rewrite(f);
for i:=1 to kz do
write(f,fish[i]);
close(f);
end;
end.