Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сборник заданий по T-Pascal.doc
Скачиваний:
65
Добавлен:
18.03.2015
Размер:
3.03 Mб
Скачать

6.3 Вариантные записи

Состав данных зависит от вида объекта, на который составлена запись. Например, если выходные данные книги содержат ее название, год и место издания, название издательства, то для журнальной статьи важно знать название журнала, номер и год выпуска. Возникает необходимость внесения в структуру записи некоторой вариантной части. С помощью записей с вариантами можно одновременно сохранять различные структуры данных, которые имеют общую часть, одинаковую во всех структурах, и небольшие отличающиеся части в различных структурах.

Вариантный записной тип - это записной тип, содержащий несколько вариантов структуры записи. Различие может касаться как числа компонент, так и их типов.

Предположим, что есть, например, такое описание:

type status = (married, widowed, divorced, single),

что означает женатый, вдовец, разведенный, одинокий. В этом случае человека можно описать с помощью данных следующего типа:

type person = record

{здесь поля общие для всех person} case status of

married: ( { поля только для семейных });

single: ({ поля только для одиноких });

end;

Каждому значению, относящемуся к типу, на основании которого идет различение вариантов (типу признака), должен соответствовать один из вариантов. Это означает, что перед вариантами должны появляться все значения типа признака. В нашем примере, кроме констант married и single, должны появиться и константы widowed и divorced.

Обычно некоторая компонента (поле) записи сама указывает, о каком варианте идет речь. В приведенном описании типа следовало бы иметь общее для всех вариантов поле ms : status. Описание определяющей вариант компоненты можно включить в заголовок варианта. Такое описание называется полем признака. Например:

case ms : status of

Прежде чем начать определять структуру записи с вариантами, соответствующую, например, типу person, полезно бывает выписать всю необходимую информацию.

1. Имя (name) - первое, последнее (first, last).

2. Рост (height) - целое число.

3. Пол (sex) - муж., жен. (male, female).

4. Дата рождения (date) - год, месяц, день (year, month, day).

5. Число иждивенцев (depds) - целое число.

6. Семейное положение (status):

Если в браке (married) или вдов (widowed):

а) дата свадьбы (mdate) - год, месяц, день (year, month, day). Если разведен (divorced):

а) дата развода (ddate) - год, месяц, день (year, month, day),

б) первый развод (firstd) - нет, да (false, true). Если одинокий (single):

информации нет.

Определение записного типа person можно сформулировать так:

type status = (married, widowed, divorced, single);

date = record

year : 1900..2100;

то : (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec);

day : 1..31;

end;

natural = O.-max;

person = record

name : record first, last: string[15] end;

height: natural;

sex : (male, female);

birth : date;

depdts : natural case ms : status of

married, widowed : (mdate : date);

divorced : (ddate : date; firstd : boolean);

single: ()

end {person};

Задача. Составить программу формирования перечня сведений по данным архива книг и журналов.

Данная задача отличается от задачи 19 тем, что состав данных в записи различается для книги и для журнала. Введем перечисляемый тип данных entrytype, определяющий варианты, type entrytype = (book, magazine).

Данные по каждому наименованию архива включают:

1) автора книги-или статьи (author) - переменная типа string;

2) наименование книги или статьи (title) - string;

3) год издания книги (журнала) - интервальный тип 1 ... 1999;

4) если книга (book):

а) издательство (publisher) - string;

б) город (city) - string. Если журнал (magazine):

а) наименование журнала (magname) - string;

б) номер журнала (vol) - integer;

в) количество страниц (page) - integer.

Программа:

program archives3;

uses crt;

label 10;

type entrytype = (book.magazine);

{Вводится специальный тип данных, определяющий варианты}

entry = record

author, title : string;

year : 1..9999;

case tag:entrytype of

{Поле tag определяет ветвь варианта}

book : (publisher,city : string);

magazine : (magname : string; vol, page : integer)

end;

var m : array[1..50] of entry;

i, j, k : integer;

ss : string;

ch : char;

begin i := 0;

{Блок формирования архива данных по книгам}

writeln (‘Пополняешь архив? - Да - [Y]');

ch := readkey;

if upcase(ch) = 'Y' then repeat i := i+1;

writeln(‘Ecли вводите данные по книге, нажмите Y ');

ch := readkey;

if upcase(ch) = 'Y' then

m[i].tag := book

{Переменной варианта присваивается признак книги - book} else m[i].tag := magazine;

writeln('Автор '); readln(m[i].author);

writeln('Название '); readln(m[i].title);

writeln('год издания '); readln(m[i].year);

{Проверка условия принадлежности объекта к книге}

if m[i].tag = book then

{Ввод данных в поля, специфические для книги} begin

writeIn (‘ Город'); readln(m[i].city);

writeln('Издательство'); readln(m[i]. publisher);

end else

{Ввод данных в поля, специфические для журнала}

begin

write ('Название журнала'); readln(m[i].magname);

writeIn(‘ Номер '); readln(m[i].vol);

writeln( 'Страница '); readln(m[i].page);

end;

writein ('Пополняешь архив? - Да - [Y]');

. ch := readkey;

until upcase(ch) <> 'Y'

else

begin write ('Вы передумали? До свидания!');

goto 10 end;

{Блок подборки списка трудов указанного автора}

repeat

writeln('Укажите фамилию автора'); readln(ss);

writeln('Список трудов ', ss : 15);

for i := 1 to k do

begin

if ss = m[i].author then

begin

writeln(m[i].title);

writeln('Год издания ',m[i].year);

if m[i].tag = book then

begin

writeln('Гopoд ',m[i].city);

writeln('Издательство ',m[i]. publisher);

writein

end

else

begin

writeln('Haзвание журнала ',m[i].magname);

writeln('Hoмep ',m[i].vol);

writeln( "Страница ',m[i].page);

writein

end

end

end;

writeln('Нужно еще выдавать авторский список? - Да -[Y]');

ch := readkey;

until upcase(ch) <> 'Y';

repeat until keypressed;

10:end.