Занятие 3. Записи с вариантами.



Записи, рассмотренные выше – это записи с фиксированными частями. Они имеют в различных ситуациях строго определенную структуру. Соответственно записи с вариантами в различных ситуациях могут иметь различную структуру.

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

Const

Kol = 1000;

Type

Entry = Record

              Autor, Title, Publisher, City : String;

              Year : 1..2000;

          End;

Var

List : Array[1..Kol] of Entry;

Что произойдет, если некоторые из входов не являются ссылками на книги, а содержат ссылки на журнальные статьи. Если ограничиваться только записями с фиксированными частями, то следует описать различные массивы для каждого вида записей. Использование записей с вариантами позволяет образовать структуру, каждый вход которой соответствует содержанию записи. Опишем новый тип, в котором перечислены различные входы:

Type

EntryType = (Book, Magazine);

Теперь можно привести скорректированное описание Entry

Type

Entry = Record

              Autor, Title : String;

              Year : 1..2000;

              Case EntryType of

                  Book : (Publisher, City : String);

                    Magazine : (MagName : String,

                                     Volume, Issue : Integer)

          End;

Это описание делится на две части: фиксированную и вариантную. Поля Autor, Title, Year составляют фиксированную часть. Оставшаяся часть описания Entry образует вариантную часть, структура которой, подобно хамелеону, может меняться в пределах двух альтернативных определений.

Первая строка вариантной части представляет оператор Case, который отличается тем, что в качестве селектора применяется идентификатор типа. Значения EntryType используются в качестве имен двух альтернатив определения записи. Когда эта компонента имеет значение Book, можно обращаться к следующим полям:

  Autor, Title, Year, Publisher, City

С другой стороны, когда она принимает значение Magazine, то можно обращаться к таким полям:

  Autor, Title, Year, MagName, Volume, Issue

В такой ситуации возникает естественный вопрос: как программа может хранить информацию о текущем состоянии каждой записи? Другими словами, каким образом можно узнать , что List[3] содержит ссылку на книгу, а List[4] – ссылку на журнал?

Естественное решение этой проблемы заключается в добавлении в каждой записи нового поля, называемого полем тега. Язык Паскаль позволяет за счет совмещения задать описание поля тега в сокращенной форме:

Type

Entry = Record

              Autor, Title : String;

              Year : 1..2000;

              Case TAG : EntryType of

                  Book : (Publisher, City : String);

                  Magazine : (MagName : String,

                                     Volume, Issue : Integer)

          End;

Поле, названное TAG, является переменной типа EntryType. Когда запись содержит ссылку на книгу, TAG следует присвоить значение Book. Когда запись содержит ссылку на журнал, TAG следует присвоить значение Magazine.

Рассмотрите последовательность операторов, где в RefList[12] помещается ссылка на книгу:

RefList[12].TAG := Book;

RefList[12].Autor := 'Thomas Hobbes';

RefList[12].Title := 'Leviathan';

RefList[12].Year := 1651;

RefList[12].Publisher := 'Andrew Crooke';

RefList[12].City := 'London';

Для определения состояния записи с вариантами достаточно проверить значение поля тега. Рассмотрите процедуру, выводящую на экран переданную ей запись.

Procedure PrintRef(Citation : Entry);

Begin

Writeln(Citation.Autor);

Writeln(Citation.Title);

Writeln(Citation.Year);

If Citation.TAG = Book

Then

    Writeln(Citation.Publisher,', ',Citation.City)

Else

    Begin

        Writeln(Citation.MagName);

        Writeln(Citation.Volume'–',Citation.Issue)

    End;

End;

Вариантная часть может содержать произвольное число альтернатив. Хотя перечисляемые типы предпочтительнее, так как они более понятны, тем не менее для именования альтернатив записи с вариантами могут использоваться идентификаторы произвольного порядкового типа.

Очевидно, что один и тот же идентификатор поля не может дважды использоваться при описании записи, даже если он применяется в определении различных альтернатив записи с вариантами. Если же это условие не выполняется, то обращение к такому идентификатору приведет к непредсказуемому результату.

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

Задание. Опишите под именем Figure вариантную запись. Если переменная типа Figure представляет собой круг, то она должна содержать радиус соответствующей окружности. Если эта переменная представляет прямоугольник, то она должна содержать величину угла и длины двух сторон, образующих этот угол и т. д. Выполните одну из следующих задач:

а) Напишите процедуру, которая запрашивает и получает значение типа Figure от пользователя.

б) Напишите функцию, которая получает на входе значение типа Figure и вычисляет площадь фигуры.

в) Напишите функцию, которая получает на входе значение типа Figure и вычисляет периметр фигуры.

г) Напишите булеву функцию, которая получает на входе два значения типа Figure и определяет, помещается ли первая фигура внутри второй.

Рассмотрите два примера решения задачи с вариантами.

Задача. В массиве хранятся данные об учениках класса: фамилия, имя, отчество, адрес (улица, дом , квартира) и домашний телефон (если есть). Вывести список учеников, до которых нельзя дозвониться.

Program LipovsevM;

Uses

Crt;

Type

Uchenik=record

                 Name:string[10];

                Fam:string[15];

                Otch:string[15];

                Ulica:string[20];

                Dom:string[5];

                Kvartira: integer;

                case tel: boolean of

                   False:();

                   True:(Telefon:string[15]);

end;

Var

Massiv : array[1..100] of Uchenik;

I,n : integer;

Otvet : 0..1;

Begin

ClrScr;

TextColor(9);

write('Введите число учеников->');

readln(n);

for i:=1 to n do

begin

   with massiv[i] do

       begin

          write('Введите имя ',i,'-го ученика ->');

          readln(name);

          write(''Введите фамилию ',i,'-го ученика ->');

          readln(fam);

          write(''Введите отчество ',i,'-го ученика ->');

          readln(otch);

          write(''Введите улицу ',i,'-го ученика ->');

          readln(ulica);

          write(''Введите дом ',i,'-го ученика ->');

          readln(dom);

         write(''Введите квартиру ',i,'-го ученика ->');

          readln(kvartira);

          write('Есть ли у ',i,'-го ученика телефон (0-нет, 1-да->');

          readln(otvet);

          if otvet=1

            then

               begin

                  tel:=True;

                  write(''Введите телефон ',i,'-го ученика ->');

                  readln(telefon);

               end;

       end;

  End;

TextColor(red);

writeln('Список учеников, до которых нельзя дозвониться:');

for i:=1 to n do

begin

    with massiv[i] do

       if tel=False

         then

            begin

               writeln('Имя:',name);

               writeln('Фамилия:',fam);

               writeln('Отчество:',otch);

               writeln('Улица:',ulica);

               writeln('Дом:',dom);

               writeln('Квартира:',kvartira);

            end;

end;

ReadKey;

End.

Задание. Будьте готовы объяснить решение предыдущей задачи и последующей учителю. Если затрудняетесь в чтении алгоритма решения задачи, то обратитесь за помощью к учителю.

Задача. Осуществить ввод общей информации (автор, название) о содержимом библиотеки: имеющиеся книги, журналы, газеты. Если книга, то осуществить дополнительно ввод года издания; если журнал – год издания и номер журнала; если газета – год, месяц и день выхода газеты. Осуществить вывод информации, поиск литературы по типу издания.

Program SedihA;

Uses

Crt;

Type

TypePubl = (Book,Journal,Newspaper);

Litter = record

             Title : string[50];

            Author : string[50];

            case V : TypePubl of

                  Вook    : (YearB : integer);

                  Journal : (Num : 1..12;

                                     YearJ : 1900..2000);

                  Newspaper : (Day : 1..31;

                                     Month : 1..12;

                                     YearN : integer);

           end;

Const

Count = 10;

Var

Katalog : array [1..count] of Litter;

NumArray : 1..count;

YesLitter : Boolean;

Vybor : byte;

Edition : Type_Publ;

CountFind : integer;

Procedure InputData;

Begin

writeln;

writeln('Введите данные о литературе ', NumArray,' :');

write('Введите число, указывающее вид издания: ');

Write('1-книга, 2-журнал, 3-газета : ');

readln(Vybor);

case Vybor of

1 : Katalog[NumArray].v:=Book;

2 : Katalog[NumArray].v:=Journal;

3 : Katalog[NumArray].v:=Newspaper;

end;

with katalog[NumArray] do

  begin

      write('Фамилия автора? ');

      readln(Author);

      write('Название? ');

      readln(Title);

      case v of

         Book      : begin

                                 write('Год издания ? ');

                                 readln(YearB);

                              end;

         Journal   : begin

                                 write('Номер ? ');

                                 readln(Num);

                                 write('Год издания ? ');

                                 readln(YearJ);

                              end;

         Newspaper : begin

                                 write('Дата издания: День? ');

                                 readln(Day);

                                 write('Месяц? ');

                                 readln(Мonth);

                                 write('Год? ');

                                 readln(YearN);

                              end;

       end;

   end;

End;

 

Procedure WriteData;

Begin

writeln;

with Katalog[NumArray] do

begin

   writeln('Название : ',Тitle);

   writeln('Фамилия автора: ',Аuthor);

   case v of

      Book            : writeln('Год издания : ',YearB);

      Journal         : begin

                                  writeln('Номер : ', Num);

                                  writeln('Год издания : ',YearJ);

                               end;

     Newspaper   : writeln('Дата издания: День: ',Day,' Месяц: ',Month,'Год: ',YearN);

   end;

end;

Еnd;

 

Procedure FindLitter;

Begin

writeln('Поиск литературы по типу издания: ');

writeln;

write('1-книга, 2-журнал, 3-газета: ');

readln(Vybor);

case Vybor of

1 : Edition:=Book;

2 : Edition:=Journal;

3 : Edition:=Newspaper;

end;

YesLitter:=False;

CountFind:=0;

for num_array:=1 to count do

if katalog[num_array].v = edition

   then

     begin

        YesLitter:=True;

        CountFind:=CountFind+1;

        WriteData;

     end;

if not YesLitter

   then

      writeln('В иблиотеке нет такой литературы')

   else

      writeln('Всего в библиотеке ',CountFind,' таких изданий');

End;

 

Begin

ClrScr;

for NumArray:=1 to Count do

InputData;

writeln;

FindLitter;

End.

Выберите с учителем задачи для решения из предложенного списка. Задачи решайте с помощью записей с вариантами. Для проверки учителем решения Вашей задачи приготовьте не только листинг и файл с протестированной задачей, но и 3-4 теста для демонстрации различных вариантов введения информации и вывода на экран.

1. Составьте список группы спортсменов, участвовавших в соревнованиях по спортивной гимнастике, включающей N человек. Для каждого гимнаста указажите фамилию, имя, название общеобразовательной школы, класс, результаты по следующим видам:

- брусья,

- вольные упражнения,

- прыжки на дорожке,

- прыжки через коня;

для юношей

- кольца,

- перекладина,

для девушек

- бревно

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

а) показавших лучший результат по каждому виду;

б) показавших лучший результат по всем видам многоборья,

в) не получивших ни одного призового места.

2. Составьте прайс-лист магазина "Техника", включающий в себя марку предприятия-производителя, страну-производитель и ,в зависимости от этих данных, наименования товара, его цену, количество единиц товара на складе. Составьте программу, которая обеспечивает ввод полученной информации, распечатку ее в виде таблицы. Выведите на экран меню, а затем информацию о товаре в зависимости от запроса покупателя.

3. Составьте прайс-лист аптеки "Эксон", включающий в себя наименования товара, страну-производитель, его цену, его состав, рекомендации врача в зависимости от возраста больного (дозировка, наличие сопутствующих расстройств). Информацию о каждом виде товара оформите в программе в виде записи с вариантами. Совокупность записей объедините в массив. Составьте программу, которая обеспечивает ввод полученной информации, распечатку ее в виде таблицы. Выведите на экран меню, а затем информацию о товаре в зависимости от запроса покупателя.

4. Составьте банк данных членов своей семьи и (или) ближайших родственников, включающий в себя имя, отчество, степень родства, и в зависимости от введенной информации в поле <МолодойСтарый> придумайте варианты полей (например, хобби, любимый анекдот, количество медалей, количество внуков, любимый напиток, любимая девочка, лучший друг, объем имеющегося наследства). Информацию о каждом родственнике оформите в программе в виде записи с вариантами. Совокупность записей объедините в массив. Составьте программу, которая обеспечивает ввод полученной информации, распечатку ее в виде таблицы. Выведите на экран меню, а затем информацию о родне в зависимости от Вашего запроса.

5. Составьте банк данных своих одноклассников, включающий в себя фамилию, имя, почтовой и (или) электронный адрес, телефон, а также в зависимости от поля <Друг> наличие соответствующей дополнительной информации по своему усмотрению. Информацию о каждом товарище оформите в программе в виде записи с вариантами. Совокупность записей объедините в массив. Составьте программу, которая обеспечивает ввод полученной информации, распечатку ее в виде таблицы. Выведите на экран меню, а затем информацию о друзьях в зависимости от Вашего запроса.

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

7. Составьте банк данных районного отдела милиции, включающий в себя фамилию, имя и отчество нарушителя, дату рождения, и в зависимости от поля <Судимость> наличие соответствующей дополнительной информации по своему усмотрению (например, наличие клички, мера наказания, срок заключения). Информацию о каждом нарушителе оформите в программе в виде записи с вариантами. Совокупность записей объедините в массив. Составьте программу, которая обеспечивает ввод полученной информации, распечатку ее в виде таблицы. Выведите на экран меню, а затем информацию в зависимости от Вашего запроса.

8. Составить программу, которая бы считывала и анализировала введенную информацию о пользователях городской телефонной сети. Запись должна иметь поля:

- фамилию, имя, отчество;

- номер телефона;

- адрес;

- наличие задолженности по оплате (в массиве по всем месяцам года).

Предусмотрите в программе варианты полей в зависимости от заполнения поля <Задолженность по оплате> (например, размер долга, отключение от междугородней сети, подсчет пени и другое).

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

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

- название авиакомпании;

- название рейса;

- номер рейса;

- тип самолета;

- даты вылета (содержатся в массиве);

- наличие мест в 1 и 2 классах;

Предусмотрите в программе варианты полей сервиса в зависимости от выбора поля <Класс>. В случае покупки билета, массив записей должен быть соответственно измениться.

10. Познакомившись с содержанием предыдущих задач придумайте свою интересную задачу и решите ее.

Дополнительно. Решение задач

Выберите с учителем задачи для решения из предложенного списка. Для проверки учителем решения Вашей задачи приготовьте не только листинг и файл с протестированной задачей, но и 3-4 теста для демонстрации различных вариантов введения информации и вывода на экран.

1. Написать программу, определяющую:

а) дату следующего (предыдущего) дня;

б) дату, которая наступит через m дней;

в) дату, которая была за m дней до сегодняшнего дня;

г) количество суток, прошедших от даты t1 до даты t2.

2. Дан массив, содержащий информацию об учениках некоторой школы.

а) Заполнить второй массив данными об учениках только девятых классов.

б) Выяснить, на сколько человек в восьмых классах больше, чем в девятых.

3. Багаж пассажира характеризуется количеством вещей и общим весом вещей. Дан массив, содержащий сведения о багаже нескольких пассажиров. Сведения о багаже каждого пассажира представляют собой запись с двумя полями: одно поле целого типа (количество вещей) и другое - действительного типа (вес в килограммах).

  а) Найти багаж, вес вещей в котором отличается не более, чем на 0.3 кг от общего среднего веса вещей пассажиров.

  б) Найти число пассажиров, имеющих более двух вещей и число пассажиров, количество вещей которых превосходит среднее число вещей.

  в) Выяснить, имеется ли пассажир, багаж которого состоит из одной вещи весом менее 30 кг.

4. В массиве хранятся данные об учениках класса.: фамилия, имя, отчество, адрес (улица, дом, квартира) и домашний телефон (если есть). Вывести на экран список учеников до которых нельзя дозвониться.

5. Дан массив данных о работающих на предприятии: фамилия, имя, отчество, адрес (улица, дом, квартира) и дата поступления на работу. Во второй массив записать данные только тех из них, кто на сегодняшний день уже проработал не менее 5 лет.

6. В массиве хранятся данные о студентах некоторого Вуза: фамилия, имя, отчество, пол, возраст, курс.

  а) Определите номер курса, на котором наибольший процент мужчин.

  б) Выведите на печать самое распространенные мужское и женское имена.

  в) фамилии (в алфавитном порядке) и инициалы всех студенток, возраст и отчества которых являются одновременно самыми распространенными.

7. Даны сведения предлагаемые к продаже на Нью-Йоркской фондовой бирже. В каждой группе записано наименование держателя акций (например IBM, GTE) и два числа, такие как 31.50 и 0.15. Эти числа представляют соответственно стоимость одной акции и размер получаемого с нее дохода (дивиденды). Программа должна определить, сколько процентов от стоимости акции приходится на дивиденды. Если окажется, что вычисленное значение превышает 10%, необходимо напечатать сообщение о том, что приобретение акций данной компании будет выгодной сделкой.

8. Для каждой из следующих задач предложите наилучший на ваш взгляд, способ представления информации: массив, запись или, может быть, только простые переменные. Обоснуйте ваши ответы.

  а) Найти среднее арифметическое из некоторого произвольного количества целых чисел.

  б) Дан список 50 имен. Необходимо проверить, не встречается ли какое–нибудь имя дважды.

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

  г) Составить список оценок студента по пяти экзаменам.

  д) Найти среднюю оценку одного студента.

  е) Разместить данные одного студента: фамилию, экзаменационные оценки и среднюю оценку.

  ж) Разместить те же данные на 50 студентов.

Приготовьте файлы с решенными задачами, проверенные листинги и тесты к задачам.


Дата добавления: 2021-04-06; просмотров: 85; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!