Файловые типы данных
Любой язык программирования содержит средства для организации хранения информации на внешних запоминающих устройствах и доступа к этой информации.
Информация на ВнУ хранится в виде файлов, под которыми понимается область памяти на ВнУ, способная хранить некоторую совокупность информации. В эту область можно как поместить определенные данные, так и извлечь из их нее. Эти операции связаны с вводом-выводом информации.
Для организации ввода-вывода в программе определяются специальные переменные файловых типов. Эти переменные являются представителями файлов в Паскаль-программе.
Длины файлов в программе не определены, но каждый файл имеет признак конца. Т.о. можно сказать, что файл – это бесконечный список значений одного и того же базового типа.
Файловый тип задается следующим образом:
Type
F = file of <тип элементов>;
Тогда
Var
Z:F; {Z – переменная файлового типа}
Или можно было сразу записать
Z: file of <тип элементов>;
Например:
Var
R: file of integer;
Тип элементов, составляющих файл, м.б. любым (и простым и сложным), кроме файлового и комбинированного типа, одним из полей которого является файл.
Type
Number = file of integer;
Wd = string [8];
Nw = file of Wd; {набор слов}
Book = record
Ch: integer;
Author: string [18];
Title: string [35];
publish: string [20];
year: 1900..1994;
end;
library = file of book;
symbol = set of ‘a’..’z’;
msimb = file of symbol; {алфавит}
var
in: number;
copir: nw;
catalog: ibrary;
azbuk: msimb;
С каждой переменной файлового типа связано понятие текущего указателя файла, каждый обозначает некоторый конкретный элемент файла.
Например: файл целых чисел имеет вид:
целое | целое | … | целое | … |
текущий указатель
Все действия с файлами, как правило, осуществляются поэтапно. Поэтому при чтении или записи участвует тот элемент файла, который обозначен текущим указателем. При работе текущий указатель перемещается по файлу, настраиваясь на тот или иной элемент.
Все элементы файла считаются пронумерованными: начальный элемент имеет нулевой номер.
Операции над файлами
Операции над файлами полностью реализованы в виде стандартных процедур и функций. Их можно разделить на четыре основных группы:
1. Установочные или завершающие операции;
2. Ввод – вывод;
3. Перемещения по файлу;
4. Специальные операции.
Установочные и завершающие оперции
1. Процедура Assign - предназначена для установления связи между конкретным физическим файлом на магнитном носителе и переменной файлового типа, которая будет представителем этого файла в программе.
Вид процедуры:
Assign (var f : name: string);
где f – файловая переменная любого файлового типа;
name – выражение строкового типа, задающее имя файла на ВнУ. Имя файла задается с помощью пути:
‘диск: \ имя директории \ имя поддиректории \ …\ имя поддиректории \ имя файла’
Если путь отсутствует, то файл ищется в текущем каталоге. Если не указан диск, то выбирается назначенный до этого по умолчанию диск.
Если name является пустой строкой, то f ассоциируется со стандартным файлом ввода- вывода (input, output).
Assign не должна использоваться для открытого файла. Имя файла должна состоять не более, чем из восьми символов, слов. Для данных обычно используется расширение dta.
Пример:
Assign(fp, ‘c:\gr221\spisok.dta');
После выполнения процедуры файловая переменная fp будет связана с файлом spisok.dta, расположенном на винчестерев каталоге gr221.
Иногда для ввода информации или ее вывода необходимо использовать специальное устройство. Для этого в качестве второго параметра в операторе assign (имя файла) используются имена, принятые в MS-DOS, такие как:
CON – консоль. Тогда для случая вывода информации помещается на экран дисплея, а в случае ввода информация воспринимается с клавиатуры.
LPT1, LPT2, LPT3 – печатающие устройства (допускается работа одновременно трех печатающих устройств). Устройств предназначены только для вывода информации.
PRN – синоним LPT1.
COM1, COM2 – последовательные коммуникационные порты. Смысл этих псевдофайлов определяется конкретными устройствами, подключенными к этим портам.
ADX – синоним СОМ1.
NUL – фиктивное, несуществующее устройство может использоваться для вывода информации в «никуда», когда в программе почему-либо нужно указать имя выходного файла, а информация, записываемая в него, не требуется.
2. Reset - процедура открывает файл, т.е. ищет файл на внешнем носителе, образует специальные буферы для обмена с файлом и устанавливает текущий указатель на начало файла ( на нулевой элемент).
Обращение:
Reset(f, [r] );
r – необязательная переменная типа word, только для нетипизированных файлов, задает размер записи, который будет использоваться для передачи данных по умолчанию.
f - файловая переменная , которая до обращения к процедуре reset уже должна быть связана с конкретным файлом процедурой assign. Если открывается несуществующий файл, то выдается ошибка.
3. Rewrite – процедура открывает файл. Причем, м.б. открыт и несуществующий файл. В этом случае процедура создает заданный файл. Если файл существует, то Rewrite его очищает.
Rewrite (f, [r]), r – для нетипизированного файла, задает размер записи.
4. Функция Append (var f: text);
где f – файловая переменная, определенная процедурой assign.
Функция открывает существующий файл, текущий маркер (указатель) файла устанавливается в конце файла.
Если такой файл не определен процедурой assign, то выдается ошибка.
Если файл уже открыт, то он закрывается, а затем открывается вновь.
5. Процедура Flush (var f:text);
где f – файловая переменная.
Процедура очищает буфер текстового файла, открытого для вывода. Очистка буфера гарантирует, что все символы, записываемые в файл в это время действительно передадутся из буфера в файл (т.е. последние элементы не потеряются, а переместяться в файл). Процедура используется редко, лучше использовать close.
6. Функция Close (var f); - закрывает файл, завершая действия с ним.
В этом случае внешний файл, ассоциированный файловой переменной f полностью закрывается, из буферной переменной передаются все значения и файл освобождается от системы обработки файлов DOS. Внутренние буферы при этом ликвидируются.
Операции ввода-вывода
1. Процедура Read (f, <список>);
где f - файловая переменная, <список> - перечень переменных, которые могут иметь различный тип. Переменные отделяются друг от друга запятыми.
Процедура предназначена для чтения данных из файла в переменные, тип которых должен совпадать с типом файла f.
Работа осуществляется следующим образом:
начиная с текущей позиции указателя файла последовательно считываются значения, содержащиеся в файле и присваиваются переменным <списка>. После каждого чтения указатель файла перемещается на следующую позицию.
Чтение прекращается, когда всем переменным будет присвоено прочитанное из файла значение.
Если файл заканчивается, а список ввода еще не исчерпан, то происходит преждевременное прекращение ввода данных и выдается ошибка – «конец файла».
2. Функция Eof (var f) – проверка на конец файла f, значение функции равно true, если текущий указатель находится за последней компонентой файла или файл пуст, в противном случае – false.
будет выделено 10 разрядов, из которых после (.) будет записано 3 разряда, переменная q запишется в ширину поля соответствующую 10 разрядам с двумя разрядами после (.).
При выводе значений в файл очередное данное записывается на место, помеченное текущим указателем. После чего текущий указатель перемещается на одну позицию.
Список значений, помещаемых в файл должен совпадать с базовым типом файла.
Перемещения по файлу
1. Процедура Seek (var f, n: longuit); - позволяет изменить положение текущего указателя, установив его на элемент файла с заданным номером. В этой процедуре f – файловая переменная, n – целая переменная типа longiut, обозначающая порядковый номер элемента файла, на который необходимо установить указатель.
2. Функция File Size (f) и File Pos (f) – позволяет получить дополнительную информацию о файле f.
File Size возвращает общее число элементов файла, а File Pos – номер элемента, на который установлен текущий указатель.
Пример: установить текущий указатель на позицию на 2 элемента большую предыдущей, т.е. пропустить 2 элемента в файле f:
Seek (f, FilePos (f) + 2);
Установить текущий указатель на начало файла:
Seek (f, 0);
Установить текущий указатель на последний элемент файла:
Seek (f, FileSize (f));
3. Truncate (f); - процедура используется для отсечения от файла его конца, начиная с текущей позиции указателя включительно.
Например: отсеч от файла с файловой переменной f все элементы, начиная с пятого.
Seek (f, 5);
Truncate (f);
Специальные операции
Операции предназначены для работы с элементами файловой системы MS-DOS - каталогами и именами файлов, позволяя создавать и удалять каталоги, удалять и переименовывать файлы.
1. Erase (f); – функция удаляет внешний файл; функция не может быть использована для открытого файла. F – файловая переменная любого типа.
2. Rename (var f, newname: string); - функция переименовывает внешний файл, имеющий файловую переменную f на имя, указанное в строковой переменной newname.
Процедура Rename не может использоваться для открытого файла.
Например:
На винчестере был файл Port.txt, переименовать его в tran.dat.
Program q (port.txt);
Var
f: text;
Begin
Assign (f,’c:\port.txt’);
Reset (f);
Close (f);
Rename (f,’tran.dat’);
End.
3. ChDir(s:string); - функция изменяет текущий директорий (справочник).
S – выражение строкового типа, соответствующее новому каталогу.
Например:
Изменить каталог Gr121 на Gr221. Сделать Gr121 – активным. Затем набрать команду ChDir(‘Gr221’).
Текущий маркер файла при выполнении Block Read (Block Write) продвигается на число записей, определенных в Result.
Перед обращением Block Read (Block Write) файл должен быть открыт.
Пример:
В файле ank.dat хранятся анкеты студентов. Содержание анкеты: фамилия и инициалы студентов (20 символов), год рождения, пол (запись).
Количество единовременно-передаваемых записей – 34, логическая запись – 30 (байт).
Подсчитать, сколько анкет относится к лицам мужского пола. Пол задан символами «муж» или «жен».
Program anket;
Type
Str = string [30];
Var
J, n, m: word;
S: array [1..34] of str; {буфер}
Fp: file; {нетипизированный файл}
Begin
N:=0;
Assign (fp, ‘Ank.dat’);
Reset (fp, 30);
While not eof (fp) do
Begin
Block Read (fp, s, 34, M); {М будет равно 34, а в конце - остатку}
For j:=1 to M do
If copy (s[j], 26, 3) = ‘муж’ then n:=n+1;
End;
Close (fp);
Writeln (‘число копий’,N:3);
End.
Один и тот же файл может быть описан в разных программах (и в одной), как текстовый, типизированный и нетипизированный. Гланое правильно использовать при этом структуру файла.
Работая с нетипизированным файлом Вы берете на себя ответственность за правильность доступа к данным. Ошибочное значение второго аргумента процедур Reset и Rewrite дезорганизует работы программы с файлом.
Пространство на диске выделяется кластерами (порциями). Кластер может занимать на диске 2 сменных сектора (это зависит от типа диска). Кластер записывается за (читается) за один оборот диска, поэтому для получения высокой скорости передачи данных размер физической записи назначают равным размеру кластера или выбирают соответствующее количество логических записей, передаваемых за один раз.
Пример:
1. Дан файл вещественных чисел
abcdabcdabcdabcd……abcd
1 2 3 4 n
В записи числа объединить по 4.
Создать новый файл так, чтобы элементы его были представлены следующим образом:
Abcdabcd …… abcd
n n-1 1
Если количество элементов в файле не кратно 4, то последнее в новый файл не писать.
Program fr;
Uses crt; {модуль работы с дисплеем}
Var
f, f1: file;
ff, ff1: text;
I, j, k, l: word;
w, x: real;
xx: array [1..4] of real;
Begin
Clrscr;
Assign (f,’ real.dat’); {для исходного массива}
Rewrite (f);
Randomize; {инициализация генератора случайных чисел}
J:=random (10);
J:=j+1; {получение случайного числа j от 1 до 11}
For i:=1 to j do
Begin
W:=random(25)/25; {получение случайного числа w от 0 до 1}
Blockwrite (f, w, size of (real)); {запись в файл f числа из переменной w. Длина числа не превышает
количества отводимого под вещественное
число}
end; {в файл f будет записано j:=11 чисел}
close (f);
reset (f); {открытие файла f для чтения}
i:=0;
repeat;
seek (f, i*size of (real)); {перемещение текущего указателя на велечину следующего указателя}
inc (i); {подсчет количества записей}
until eof(f);
del (i);
writeln (‘количество записей в файле =’,i);
j:= I mod 4; {для определения кратно ли количество записей в файле 4}
l:= I div 4; {количество записей, объединенных по 4 числа}
assign (f1,’rev.dat’);
rewrite(f1);
for k:= l downto 1 do
Begin
Seek f, (k-1) * size of (xx)); {перемещение на начало
очередных четырех чисел}
blockread (f, xx/ sizeof (xx)); {считывается очередных числа,
начиная с конца }
blockwrite (f1, xx, sizeof (xx)); {запись очередных четырех
чисел, начиная с начала}
end;
close (f), close (f1); {формирование обычных файлов вещественных
чисел, удобных для восприятия}
reset (f); {исходящий}
reset (f1); {полученный}
reset (ff, ‘dir’);
assign (ff1, ‘rev’);
rewrite (ff); {файлы вещественных чисел, записанных по одному
rewrite (ff1); числу в символьном виде}
while not eof (f) do
Begin
Blockread (f, x, sizeof (real); {считывание одного числа из
исходного файла}
write (ff, x:6:3,’); {запись очередного числа в файл ff с
шириной поля - 6 и тремя знаками после
запятой через пробел, числа отделяются
друг от друга запяттой}
end;
writeln (ff);
while not eof (f1) do
begin
blockread (f1, x, sizeof (real)); {действия для полученного
файла аналогично исходному}
write (ff1, x:6:3,’ ‘);
end;
writeln (ff1);
close (f);
close (f1);
close (ff);
close (ff1);
end.
Работа с текстовыми файлами
Для описания символьных (текстовых) файлов используется стандартный тип text. К текстовым файлам относятся стандартные файлы input и output. Их особенность:
1. Такие файлы могут быть разбиты на строки с помощью специального символа, который не включен в стандартный тип char. Конкретная реализация этого символа зависит от типа машины и не имеет в данном случае значения.
2. Конец строки определяется функцией eoln (f); f – файловая переменная. Она принимает значение true, если конец строки достигнут и – false в противном случае. При достижении конца строки значение буферной переменной файла соответствует значению пробела.
Примеры:
1. Создать файл Spidor содержащий записи с порядковым номером и фамилиями и инициалами студентов. Порядковый номер целое число, фамилия и инициалы – содержат 16 символов максимум. Список будет содрежать 25 человек.
Program grup (input, output, spisok);
Const
Maxd = 16;
K=25;
Type
Name = record
N: integer
Sname: packed array [1..maxd] of char;
End;
Var
Vn: name;
Spisok: text;
I:1..maxd;
J: integer;
Begin
J:=1;
Assign (spisok,’gruppa’);
Rewrite (spisok); {rewrite, т.к. открывает несуществующий файл}
Repeat
For i:= 1 to maxd do
Read (vn. Sname [i]); {чтение фамилии}
Vn.n:= j;
Writeln (spisok, vn.n, vn.sname);
Inc(j);
Until j>k;
Close (spisok);
End.
2. Прочитать созданный файл и распечатать список студентов.
Program grup1 (input, output, spisok);
Const
Maxd = 16;
Type
Name = record
N: Integer;
Sname: packed array [1..maxd] of char;
End;
Var
Vn: name;
Spisok:text;
j:= j + 1; {формирование длины строки}
nd; {while} {прочитаны строки текста}
k:=1; {начальное значение указателя символа b}
repeat
with tt do
case st1 [k] of
‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’:
begin
i:= wd;
n:=0;
repeat
n:=n+1;
c [n]:=st1[k];
k:=k+1;
end;
‘,’, ‘.’, ‘:’, ‘;’:
Begin
i:= pun;
simb:= st1[k];
end;
‘ ‘: k:=k+1;
end; {оператора case}
end; {оператора with}
until k>j; {конец оператора repeat}
end.
В результате работы программы в записи tt 0. Содержаться сведения об одном из видов считанной информации: о слове или о знаке препинания. Для обработки другого вида информации данная программа не предназначена.
Комбинированный тип данных
Комбинированный тип данных или записи позволяют объединять значения различных типов данных (символьные, целые, вещественные, например данные о человеке: фамилия, пол, инициалы).
Такая разнородная, но логически связанная информация не может идентифицироваться (обозначаться) порядковыми номерами, как в массивах, поэтому для обозначения различных составляющих записи используются идентификаторы – поля.
Т. о. запись будет иметь какое-то имя, а затем после ключевого слова record перечисляются все имена полей, входящий в эту запись, с указанием их типов. Заканчивается запись ключевым словом end.
Например:
Словарь содержит исходные данные слова и их значения (перевод), поэтому каждую строку словаря можно представить в виде следующей записи.
Type
Wd = record
W: packed array [1..16] of char;
M: packed array [1..20] of char;
End;
Var
Wr: wd;
Имена w и m – это идентификаторы поля переменной w2, имеющей комбинированный тип wd. Переменную wr можно описать без использования раздела type:
Var
Wr: record
W: packed array [1..16] of char;
M: packed array [1..20] of char;
End.
Более сложная запись будет о книгах, помещенных в каталогах:
Type
Book = record
Ch: integer;
Author: packed array [1..18] of char; {автор}
Title: packed array [1..20] of char; {издательство}
Year: 1900…1996; {год издания}
End;
Var
Textbook, monogr, spav: book; {учебник, монография, справочник}
Записи представляют собой структуры с прямым методом доступа, т.е. можно выбрать любое поле записи без перебора предыдущих полей. Уникальность имен полей требуется только внутри одной записи. Идентификаторы полей могут совпадать с идентификаторами полей других записей или просто с другими именами переменных. Это возможно потому, что идентификатор поля используется только в паре с именем записи, т.е. обращение к полям осуществляется с помощью конструкции, называемой селектором записи, имеющей следующий вид:
Z, p;
где z – переменная комбинированного типа (имя записи);
p - идентификатор поля.
Например:
Для словаря справедлива запись:
Wr.w:= ‘table’;
Wr.m = ‘стол’;
Данные о монографии в каталоге могут быть следующими:
Monogr.ch:= 2212;
Monogr.author:= ‘К.Йенсен, Н.Вирт’;
Monogr.title:= ‘Паскаль’;
Monogr.publish:= ‘Финансы и статистика’;
Monogr.year:= 1982;
Если все данные о монографии, необходимо поместить в переменную textbook, имеющую тот же комбинированный тип данных, что и monogr, то это можно сделать одним оператором присваивания:
Textbook:= monogr;
Такое обращение к записи в целом возможно только в операторе присваивания, где слева и справа используются записи одинакового типа. Во всех остальных случаях оперируют отдельными полями записей.
Комбинированные типы можно использовать для построения более сложных структур, например, массивов, состоящих из записей:
Например: англо-русский словарь может быть описан следующим образом:
Type
Wd = record
W: packed array [1..16] of char;
M: packed array [1..20] of char;
End;
Book = array [1..3000] of wd;
Var
Er: book; {словарь}
Переменная er – это массив из 3000 записей, содержащих английские слова и их русские значения. Доступ к полям записей, составляющих массив er, производится следующим образом:
Er[i].w:= ‘pencil’;
Er[i].m:= ‘карандаш’;
Комбинированные типы данных могут также иметь структуру, в которой содержаться поля, имеющие также тип записи.
Например:
Данные о каждом человеке могут иметь информацию такую: имя, отчество, фамилия – это строковые данные; пол – женский или мужской; специальность – целое число; данные о дате рождения – запись, содержащая сведения о дне, месяце и годе рождения.
Тогда запись, содержащая сведения о человеке будет иметь вид:
Type
Date = record {дата рождения}
Month: (Jan, Feb, Mar, Apr, May, June, July, Aug, Sept, Oct, Nov, Decem);
Day: 1..31;
Year: 1900…1996;
End;
Person = record
Name, SecondName, Surname: string[20]; {имя, отчество, фамилия}
Sex: (male, Female); {пол}
Speciality: word; {специальность}
BirthDay: date; {дата рождения}
End;
Var
Child: person;
Доступ к полям любой записи осуществляется по общим правилам, например:
Child.name:=
Child. Secondname:= ‘Александр’;
Child. Surname:= ‘Николаевич’;
Child. Sex:= male;
Child. Speciality:= 1204;
Child. BirthDay. Day:= 1;
Child. BirthDay. Month:= Feb;
Child. BirthDay. Year:= 1980;
Таким образом, необходимо помнить слева от символа ‘.’ всегда должна находиться переменная типа запись, а справа идентификатор поля этой записи.
Пример:
Англо-русский словарь содержит 3000 слов. Найти заданное слово в словаре и определить его значение. Каждая строка словаря занимает одну строку файла input.
Program mer;
Const
Amount = 3000; {количество слов}
Type
Wd = record {строка словаря}
W: string [16];
M: string [20];
End;
Book = array [1…amount] of wd; {словарь}
Var
Er: book;
Wr: wd; {запись слова}
Z: string [16]; {заданное слово}
I: 1…amount;
K: 1..16;
J: 1..20;
Begin
For i:= to amount do
Begin
Read (wr.w); {ввод слова}
Read (wr.m); {ввод перевода]
Readln; {формирование словаря}
Er[i]:= w;
End;
Read (z); {чтение заданного слова}
For i:= 1 to amount do {перебор слов}
If z = er [i]. w then {нашли слово в словаре}
Writeln (er [i].m); {печать перевода слова}
End.
Оператор with
Обращение к компонентам записи можно упростить, если воспользоваться оператором присоединения with. Он позволяет вывести имена записи в заголовок и затем оперировать не составными именами (<запись>, <поле>), а просто именами полей.
Оператор with имеет вид:
With <имя записи> do
<операторы, содержащие имена полей записи>;
Например:
Занесение сведений о книге К. Йенсен, Н. Вирт «Паскаль» в запись book м. б. сделана следующим образом:
Program ab;
Type
Book = record;
Ch: integer; {шифр}
Author: packed array [1..18] of char; {автор}
Title: packed array [1…35] of char; {название}
Publish: packed array [1….20] of char; {издательство}
Year:1900….1996; {год издания}
End;
Var
Textbook: book;
Begin
With textbook do
Begin
Ch:= 2212;
Author:= ‘К. Йнсен, Н. Вирт’;
Title:= ‘Паскаль’;
Publish:= ‘Финансы и статистика’;
Year:= 1982;
End;
End.
Пример:
В библиотеке хранится до 2000 книг, каждая из которых имеет автора, название, издательство, год издания. Проверить, есть ли в библиотеке книги К. Йенсен, Н. Вирт «Паскаль». Если данной книги нет, то включить ее в состав библиотеки. Считаем, что алфавитный каталог составлен по фамилиям авторов.
Program Search;
Label 1, 2;
Const
Amount = 2000; {количество книг}
Type
Book = record
Author: packed array [1..18] of char; {автор}
Title: packed array [1…35] of char; {название}
Publish: packed array [1…20] of char; {издательство}
Year: 1990….1996; {год издания}
End;
Library = array [1…amount] of book ; {библиотека}
Var
Ib, kb: book;
Catalog: library;
I, n : 1….amount;
K: integer;
Begin
For i:=1 to amount do
Begin
For k:= 1 to 18 do read (kb. Author [k]); {ввод автора}
For k:= 1 to 35 do read (kb. Titly [k]); {ввод названия}
For k:= 1 to 20 do read (kb. Title [k]); {ввод издательства}
Read (kb. Year); {ввод года издания}
Readln;
Catalog [i]:= kb; {сформированная запись о книге вводится в каталог}
End; {for i}
With ib do
Begin
Author:= ‘Йнсен К., Вирт Н.’;
Title:= ‘Паскаль’;
Publish:= ‘Финансы и статистика’;
Year:= 1982;
End; {Сведения об искомой книге}
For i:= 1 to amount do {поле книги в каталоге}
If catalog [i].author > = ib.author then
Begin
If catalog [i].author = ib.author then
Begin
Writeln (I, ‘ – номер книги в каталоге’);
Goto 1; {exit} или {Halt}
End; {then}
Else
Begin
N:=I; {Место куда нужно включать книгу}
Goto2;
End; {else}
End; {then}
Writeln (‘Данной книги в каталоге нет, введем ее вместо последней книги’);
N:=amount;
Catalog [n]:= ib;
Goto 1; {exit} {halt}
For i:= amount downto n+1 do
Catalog [i]:= catalog[i-1]; {сдвиг содержимого каталога}
Catalog [n]:= ib; {включение книги в каталог}
For i:=1 to amount do {распечатка каталога}
Begin
Bb:=catalog [i];
With kb do
Begin
Writeln (author);
Writeln (title);
Writeln (publish);
Writeln (year);
Writeln;
End; {with}
End;
End.
Оператор With может иметь вложенную структуру с любой степенью вложенности.
Например:
Var
X: record
A: record
B: record
C: real
D: integer
End; {b}
E: bolean;
end; {x}
f: char;
end; {x}
Пусть с необходимо присвоить значение 17.3. Тогда обращение к полю с, которое записывается составным именем x. a. b. c. может быть записано оператором присоединения with.
With x do
With a do
With b do
C:= 17.3;
Или with x, a, b do c:= 17.3;
Если необходимо задать c:= 17.3; d:= 18; c:= true и f = ‘Q’, то это будет выглядеть так:
With x do
Begin
F:=’Q’;
With a do
Begin
C:= true;
With b do
Begin
C:= 17.3;
D:= 18;
End; {with b}
End; {with a}
End. {with x}
Переменная структура записи
Очень часто в пределах одной записи требуется различная информация в зависимости от конкретного значения поля.
Например: при описании данных о гражданине для мужчины необходимо включать данные о том служил, ли он в армии, находится на воинском учете или снят с него; данные о том, курит ли он. Для женщин эти сведения не нужны.
Варианты могут содержать различное количество и типы полей. Необходимо отметить, что:
1. При определении комбинированного типа данных в нем может быть только одна вариантная часть, которая задается в конце записи (т.е. сначала идет общее описание с вариантами и в конце ставится end;).
2. Имя переменной (в нашем примере trud) называют дискриминантом записи и находится в заголовке вариантной части. Ее значение определяется в зависимости от типа, который задается идентификатором, описанным в разделе типов отдельно (eiter). Причем, тип этот должен быть перечисляемым.
3. Идентификаторы полей во всех вариантах должны быть различными и не совпадать ни с одним из идентификаторов фиксированной (постоянной) части.
4. Для некоторых значений поля – дискриминанта вариант может отсутствовать. В этом случае после метки варианта стоит пустой список ().
При использовании записей с вариантами необходимо помнить, что для размещения переменной комбинированного типа всегда отводится фиксированный объем памяти. Причем, для записи с вариантами этот объем определяется по самому большому варианту. Т.о. различные варианты одной записи занимают одну и туже область памяти, как бы «накладываются» друг на друга. Это нужно учитывать при составлении программы.
Пример:
Пусть имеется список литературы, состоящий из 50 наименований, описанной в разделе описания переменных и содержащий конкретные сведения обо всех литературных источниках. Необходимо записать на пятое место в этом списке новые данные о литературном источнике, который является монографией.
.
.
.
var
spisok: array [1…50]
begin
with spisok [5] do
begin
author:= ‘П. Гроного’;
title:= ‘Программирование на языке Паскаль’;
trud:= monogr;
town:= ‘Москва’;
publish:= ‘Мир’;
year:= 1990;
end;
end.
Пример:
Пусть необходимо выбрать из списка литературы данные о первом наименовании в этом списке и напечатать их:
.
.
.
var
spisok: array [1..50] of istochnic;
i: liter;
Begin
With spisok [1] do
Begin
Writeln (author);
Writeln (title);
Case I of
Monogr: Begin
Writeln (town);
Writeln (publish);
Writeln (year);
End;
Gurnal: Begin
Writeln (titleg);
Writeln (number);
Writeln (yearg);
End;
Tronf: Begin
Writeln (titlek);
Writeln (townk);
Writeln (yeark);
End;
End; {case}
End; {with}
End.
Дата добавления: 2016-02-24; просмотров: 1975;