Порядок работы с файлами произвольного доступа.
При решении научно- технических и экономических задач обработки совокупностей большого количества значений используются массивы. Но при работе с массивами основное ограничение заключается в том, что каждый элемент массива должен иметь один и тот же тип данных.
Иногда для решения задач, в которых возникает необходимость хранить и обрабатывать совокупности данных различного типа, используются записи.
Запись представляет собой наиболее общий и гибкий структурированный тип данных, так как она может быть образована из не однотипных компонентов и в ней явным образом выражена связь между элементами данных, характеризующими реальный объект.
Запись -это структурированный тип данных, состоящий из фиксированного числа компонентов, называемых полями записи. Определение типа записи начинается идентификатором Record и заканчивается зарезервированным словом end. Между ними заключен список компонентов, называемых полями, с указанием имен полей и типа каждого поля.
|
|
Структура объявления типа записи такова:
type <имя типа> = record
<идентификатор поля>:<тип компонента>;
<идентификатор поля>:<тип компонента>
end;
var <идентификатор,…>: <имя типа>;
Пример описания записи:
Type Car=Record
Number: integer; {Номер}
Marka: string[20]; {Марка автомобиля}
FIO: string[40]; {Фамилия, инициалы владельца}
Address: string[60] {Адрес владельца}
End;
Var Mashina: Car;
В данном примере была объявлена запись с именем Car, у которой имеется 4 поля: номер, название марки машины, ФИО владельца и его адрес.
Идентификатор поля должен быть уникален только в пределах записи, однако лучше его сделать уникальным в пределах всей программы. Объем памяти, необходимый для записи, складывается из длин полей. Значения полей записи могут быть использованы в выражениях. Обращение к значению поля осуществляется с помощью идентификатора переменной и идентификатора поля, разделенных точкой. Такая комбинация называется составным именем.
Например, доступ к полям записи Car осуществляется как: Mashina.Marka, Mashina.FIO, Mashina.Number. Составное имя можно использовать везде, где допустимо применение типа поля. Для присваивания полям значений используется оператор присваивания.
Пример присваивания полям записи Mashina:
Mashina. Number:=164536l;
Mashina.Marka:=’ГАЗ-24’;
Mashina.FIO:=’Иванов И.И’;
Mashina. Address:=’ул.Пушкина 12-30’;
Составные имена можно использовать в операторах ввода-вывода:
Read (Mashina. Number, Mashina. FIO, Mashina. Address);
Write(Mashina. Number:4, Mashina. FIO:12, Mashina. Address:25);
Допускается применение оператора присваивания и к записям в целом, если они имеют один и тот же тип. Например,
Mash:=Mashina;
После выполнения этого оператора значения полей записи Mash станут равны значениям соответствующих полей записи Mashina.
|
|
В ряде задач удобно пользоваться массивами из записей. Их можно описать следующим образом:
Type Car=Record
Number:Integer;
Marka:String[20];
FIO:String[40];
Address:String[60];
End;
Var Mashins: array [1..20] of Car;
Обращение к полям такой записи имеет громоздкий вид, для решения этой проблемы в языке Паскаль предназначен оператор With, который имеет следующий формат:
With <переменная типа запись> do <оператор>;
Один раз, указав переменную типа запись в операторе With, можно работать с именами полей как с обычными переменными.
Пример присвоения значения полям записи Car с помощью оператора With.
With Mashina do
Begin
Number:=164536l;
Marka:=’ГАЗ-24’;
FIO:=’Иванов И.И’;
Address:=’ул.Пушкина 12-30’;
End;
Рассмотрим случай, когда в составе записи содержатся поля, имеющие тип записи. Пусть для комбинированного типа VEDOM необходимо хранить информацию о дате сдачи экзамена. Эту информацию можно представить в виде трех полей: месяц, день, год, дополняющих предыдущий состав типа VEDOM. Однако, логичнее дату сдачи экзамена определить как отдельный тип. Это позволит использовать тип DATE в описании других типов и переменных:
TYPE Date = RECORD
Mounth: (jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec);
Day: 1..31;
Year: 1900..2000
END;
Теперь тип DATE можно использовать в записи VEDOM:
TYPE Vedom = RECORD
N: integer;
Fio: string[15];
Progr,Fizika: integer;
D_exem: date
END;
Доступ к полям D_EXEM осуществляется по общим правилам, т.е. при записи селектора слева от символа 'точка ' всегда должна находиться переменная типа запись, а справа идентификатор поля этой записи, например:
Vedom.D_exem.Mounth:= jan;
Vedom.D_exem.Day:= 25;
Комбинированный тип может употребляться для спецификации параметров подпрограмм.
Записи с вариантами
Часто в зависимости от конкретного значения некоторого поля возникает необходимость в пределах одной записи иметь различную информацию. В таких случаях используются записи с вариантами. Записи с вариантами имеют фиксированную и вариантную части.
Вариантная часть формируется с помощью оператора Case. Он задает особое поле записи-поле признака, которое определяет, какой из вариантов в данный момент будет активизирован. Значением признака в каждый текущий момент выполнения программы должна быть одна из расположенных далее констант. Константа, служащая признаком, задает вариант записи и называется константой выбора.
Формат:
Type
<имя типа> = Record
Case <поле признака>: <имя типа> of
<константа выбора 1>: (поле, …: тип);
…
<константа выбора n>: (поле, …: тип);
End;
Компоненты каждого варианта (идентификаторы полей и их типы) заключаются в круглые скобки. У части Case нет отдельного end. Одно слово end заканчивает всю конструкцию записи с вариантами. Количество полей каждого из вариантов не ограничено. Объем памяти, необходимый для записи с вариантами, складывается из объемов полей фиксированной части и максимального по объему поля переменной части.
Пример:
Type
Rec= Record
Number:Byte;
Code:Integer;
Case Flag:Boolean of
True:(Price1:Integer);
False:(Price2:Real);
End ;
Var PRec: Rec;
В данном примере была объявлена запись с именем Rec, у которой поля Number и Code расположены в фиксированной части записи, они доступны в программе в любой текущий момент независимо от значения поля признака. Поле Price 1 может использоваться только в том случае, если значение поля признака Flag равно True. Поле Price 2 доступно в противоположном случае, т.е. если значение Flag равно False.
При использовании записей с вариантами необходимо придерживаться следующих правил:
1. все имена полей должны отличаться друг от друга, по крайней мере, одним символом, даже если они встречаются в разных вариантах
2. запись может иметь только одну вариантную часть, причем вариантная часть должна размещаться в конце записи
3 если поле, соответствующее какой-либо метке, является пустым, то оно записывается следующим образом: < метка>: ();
|
|
Рассмотрим тип PERSON, содержащий информацию о человеке.
Если поле POL имеет значение М (мужской), то пусть необходимо предусмотреть такие поля:
- служил в армии или нет;
- если служил, то дату последних военных сборов.
Если поле POL имеет значение W (женский), то необходима информация о цвете глаз.
Запись с вариантами типа PERSON имеет вид:
Type Date = Record
Mounth: (jan,feb,mar,apr,may,jun,jul,aug, sep,oct,nov,dec);
Day: 1..31;
Year: 1900..2000
End;
Person = Record
Fio: string[20];
Special: word;
Birthday: date;
PersonPol: (M,W);
Case
pol: PersonPol of
M: (Army: boolean; D_Army: date);
W: (EyesColor: (blue,brown, gray,green))
End;
Изменяющаяся часть записи называется вариантом. Вариант всегда располагается в конце записи. Поле (в данном случае POL), позволяющее различать варианты, называется полем признака. Вариантная часть содержит несколько альтернатив (в данном примере - M и W), в каждой из которых в круглых скобках задается список полей, присущих данному варианту (ARMY и D_ARMY.M, EYESCOLOR.W). Списку полей предшествует метка, являющаяся конкретным значением признака POL. Метка служит критерием выбора вариантов. Перечисление альтернатив начинается с определения признака POL.
Любой вариант, в свою очередь, может иметь свою вариантную часть, которая должна располагаться в конце списка полей данного варианта.