69115

Записи. Запис та його оголошення. Доступ до компонентів та операцій над записами. Масиви записів. Записи з варіантами

Лекция

Информатика, кибернетика и программирование

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

Украинкский

2014-09-30

100 KB

1 чел.

Лекція 24. Тема:Записи. Запис та його оголошення.

                        Доступ до компонентів та операцій над записами.

                        Масиви записів. Записи з варіантами.

План:

1. Записи

2. Запис та його оголошення

3. Доступ до компонентів та операції над записами

4. Масиви записів

5. Записи з варіантами

1. Записи

У попередньому розділі було розглянуто одну з найважливіших структур даних -масив. Визначальною характеристикою масиву є однорідність, тобто однотипність його елементів. Проте реальний світ насичений неоднорідними структурами даних. Прикладами таких структур можуть стати: календарна дата, що скла-дається з номера дня, номера року та назви місяця, особова картка працівника (прізвище, адреса, дата народження, прибуток тощо), відомості про товар (назва товару, ціна, виробник, номер сертифіката якості тощо). Зрозуміло, що масив не є зручним та адекватним засобом зберігання структур різнотипних даних. Адже для зображення, скажімо, множини календарних дат довелося б створити три масиви: цілочислові масиви років і номерів днів, а також рядковий масив назв місяців. Такий спосіб зберігання даних є потенційно небезпечним, оскільки, зокрема, не виключає можливості зсуву в масиві місяців без відповідного зсуву в масиві днів. Отже, обробка згаданих масивів має проводитись синхронно і тому є достатньо складною задачею. Набагато зручніше було б створити один масив, що зберігатиме календарні дати як структури. Кожна із структур міститиме дані різних типів, але при цьому всі структури належатимуть тому самому структурованому типу даних. Структури, що можуть об'єднувати дані різних типів, в мові Раsсаl називаються записами. Записам і присвячено розділ 8.1.

2. Запис та його оголошення

Запис - це структурований тип даних, що являє собою об'єднання фіксованої кількості змінних одного або декількох типів. Змінні, що входять до складу запису, називаються його полями. Можливість інтегрування в один запис різнотипних компонентів становить головну відмінність запису від масиву. Зауважимо, що, на відміну від терміна «масив», терміном «запис» позначатимемо саме тип даних, а дані цього типу називатимемоекземплярами записів.Таке застосування терміналогіїпояснюється тим, що для типу запису, як правило,оголошується окремий ідентифікатор, а типе масиву найчастіше оголошується неявно, разом із оголошенням зміної масиву.

Оголошення записів як титів даних здійснюються в розділі type Pascal-програми. Після цього їх можна використовувати для оголошення змінних типу запису - це робиться в розділі оголошення змінних var. Оголошення  запису та змінної типу запису має такий вигляд:

type<ім’я типу> = record

                                <ім’я поля1>:<тип>;

                                 …

                                <ім’я поляN>:<тип>;

                            end;

var <ім’я зміної>:<ім’я типу>;

Оголошення типу розпочинається ключовим словом гесord і завершується словом end. Між цими словами міститься список оголошень полів. Кожне поле оголошується як ідентифікатор зміної певного типу. Зазначимо, що ім’я поля має бути унікальним в межах запису. Наведемо приклади оголошень записів і змінних відповідних типів.

Приклад 8.1

type

date=record

        day:1..31;

        month:string;

        year:1..2010;

    end;

person=record

        first_name:string;

        last_name:string;

        address:string;

        birthday:date;

       profit:real;

    end;

produce=record

       name:string;

       price:real;

       producer:string;

      certification:integer;

    end;

var d:date;

     man:person;

     item:produce;

Поле запису може мати будь-який тип, крім файлового. Зокрема воно може бути змінною структурованого типу. Обсяг пам’яті що виділяється транслятором для зберігання даних типу запис, визначається як сума обсягів областей пам'яті, що виділена для зберігання всіх його полів. Так, для зберігання даних типу date з наведеного вище прикладу потрібно 259 байт пам'яті (1+256+2), а даних типу person - 1033байт(256*3+259 + 6)

Записи можна використовувати і для створення типізованих констант. Наприклал, константа VictoryDay оголошеного у прикладі 8.1 типу date може мати такий вигляд:

Const VictoryDate:date =  (day:9; month: ‘may’; year:1945);

3. Доступ до компонентів та операції над записами

У розділі 8.1.1 згадувалося, що під час оголошення запису кожен його компонент позначається ідентифікатором, який має бути унікальним у межах запису. Але слід зауважити, що імена полів різних записів можуть збігатися. Тому звернення до компонентів записів здійснюється через складене ім’я,  що має такий синтаксис:

<ім’я змінної типу запису>.<ім’я компонента>

Крапку, що записується між іменем запису та іменем компонента, інколи називається символом оператора доступу. Якщо екземпляр деякого запису є полем іншого залису, то складені імена полів такого екземпляра міститимуть декілька символів оператора доступу. У прикладі 8.1 розглядається запис person (людина), поле birthday (день народження) котрого є екземпляром іншого запису – date. У такій структурі ідентифікатор man.birthday.year адресує рік народження людини man. Складність доступу до компонентів записів може бути зменшена, якщо використати конструкцію with, яку ще називають оператором приєднання. Синтаксис конструкції with такий:

with <список змінних типу запис> do

begin

   <оператори>

end;

В операторах всередині конструкції with замість імен змінних типу запис вказуються лише імена полів. Для однієї конструкції with розповсюджується на вміст лише одного складеного оператора і лише на ті записи, імена яких були вказані у списку змінних типу запис.

Приклад 8.2

Нєхай оголошено запис person (ім'я, адреса, день народження, прибуток), у якому компонент «адреса» сам має тип запису home_address із компонентами «місто», «вулиця», «номер будинку». Схематично структуру екземпляра man запису person зображено на рис. 8.1, а нижче наведено програму, що ініціалізує поля first_name та address цього запису.

type

  home_address=record

      town:string;

      street:string;

      house:byte;

    end;

    person=record

      first_name:string;

      last_name:string;

      address:home_address;

      birthday:string;

      profit:real;

    end;

var man:person;

begin

    with man, address do

    begin

       first_name:=’Ivan’;

       town:=’Kiev’: street:=’Victory’; house:=42;

   end;

end.

Якщо ім'я відповідної структурної змінної в конструкції with не вказано, для цієї конструкції не поширюється на поля даного запису, наприклад,

with man do

begin

   first_name:=’Ivanov’;

   address.town:=’Kiev’;

   address.street:=’Victory’;

   address.house:=42;

end.

Над компонентами записів можна здійснювати будь-які операції, що є допустимими для типів цих компонентів. Для екземплярів запису як цілісних об'єктів означена тільки одна операція - присвоєння. Слід пам'ятати, що присвоєння значення змінній деякого типу запису призведе до присвоєнь значень всім полям цієї змінної. Присвоєння значень змінних типу запису іншим змінним можливе тільки за умови їх однорідності, тобто змінні, що берутъ участь у присвоєнні, повинні мати однаковий склад компонентів та їх типів. Наприклад, для оголошенних нижче змінних z1 та z2 присвоєння є коректним.

var z1, z2:record

                    str:string;

                    number:read1;

                 end;

begin

  z1:=z2;

end.

Приклад 8.3

Розглянемо приклад, у якому екзкмпляри записів обмінюються значеннями. Припустимо, що оголошено тип person і у змінні man1 та man2 введені значення прибутку.Треба упорядкувати два записи так, щоб у змінній man1 зберігалися відомості про ту людину, доход якої більший.

type person=record          {оголошення типу запису}

          first_name:string;  {ім’я людини}

          profit:real;             {доход}

       end;

var man1,man2,tmp:person;   {екземпляри записів, що обмінюються значеннями}

begin

  writeln(‘Введіть компоненти записів’);

  with man1 do  {ініціалізація компонентів}

  begin

     first_name:=’Ivanov’;

     readln(profit);

   end;

   with man2 do

   begin

     first_name:=’Petrov’;

     readln(profit);

   end;

   if man1.profit<man2.profit then

   begin             {обмін значеннями між компонентами}

     tmp:=man1;

     man1:=man2;

     man2:=tmp;

   end;

   with man1 do    {вивести значення компонентів на екран}

   begin

      writeln(first_name);

      writeln(profit);

   end;

   with man2 do

   begin

      writeln(first_name);

      writeln(profit);

   end;

   readln;

end.

4. Масиви записів

У прикладах, що розглядалися раніше, використовувалися лише окрємі змінні типу запису. Але в практичних задачах записи частіше використовуютъся як складові частини масивів, списків, дерев та інших структур. Як приклад такого використання записів розглянемо задачу створення телефонного довідника. У цьому довіднику зберігається однотипний набір даних про всіх абонентів: телефоний номер, прізвище й адреса його власника. Отже, телефонний довідник містить набір записів, що маютъ однакову структуру. Тому найбільш природною формою зберігання інформації телефонного довідника буде масив записів.

Елєменти масиву записів обробляютъся так само, як інші змінні типу запису, зокрема їх можна використовувати в конструкиції with. При зверненні до полів запису, що є елементом масиву, застосовуються дві операції: індексування ([ ]) i доступу до компонента (.). Порядок запису символів згаданих операцій є таким:

<ім’я масиву записів>[<індекс компонента масиву записів>].<ім’я поля>

Якщо операція індексування [ ] застосовується до масиву, який є компонентом запису, то маємо синтаксичну конструкцію іншого вигляду:

<ім’я зміної типу запис>.<ім’я поля запису>[<індекс компонента масиву>]

Але повенімося до задачі складання й обробки телефонного довідника.

Приклад 8.4

Створимо телефонний довідник, дані до якого користувач вводить із клавіатури. Треба здійснити виведення даних, сортування записів довідника за алфавітом і пошук номера потрібного абонента. Для розробки програми застосуємо метод низхідного проектування, розглядаючи всю програму як набір процедур, що ви-конують деякі легко означувані операції. Одна з процедур - процедура введення даних, яку назвемо create. Ця процедура послідовно заповнюватиме елементи масиву записів. Після введення кожного запису користувачеві буде задане питання ‘continue? y/n’ (продовжувати? так/ні). Цикл введення триває доти, доки користувач у відповідь не натисне клавішу N. Виведення даних здійснюватиме процедура print, що переглядає та виводить на екран всі записи, поки не буде досягнуто кінця масиву. Дані у довідниках впорялковуються за певним ключей, котрим вважатимемо ім'я абонента.

Сортування записів довідника за іменами абонента виконуватиме процедура sort, використовуючи при цьому алгоритм сортування методом обміну (бульбашкове сортування), який було розглянуто у прикладі 7.11. В упорядкованому иаборі даних можна здійснити швидкий бінарний ношук, алгоритм якого розглянуто у розділі 7.1.2. Процедуру пошуку назвемо BinSearch. Щоб визначити, чи був пошук успішним, скористаємося булевою змінною flag. Для збергання записів довідника оголосимо тип запису data, що містить у полях рядкового типу ім'я абонента, його адресу та номер телефону, а також оголосимо масив directory записів типу data.

program ex8_1;

uses crt;

type data=record     {тип записів довідника}

       user_name:string;   {прізвище абонента}

       address:string;     {адреса абонента}

       phone:string;   {телефон абонента}

     end;

var

   directory:arrey [1..10] of data;  {масив записів довідника}

   number:integer;  {кількість записів}

   middle:integer;  {індекс середнього компонента}

   name:string;   {ім’я для пошуку}

   flag:boolean;  {ознака успішності пошуку}

{=================створення масиву записів================}

procedure create;

var key:char;      {код натиснутої клавіші}

     i:integer;       {індекс компонента масиву}

begin

  writeln(‘enter directory data’);

  i:=0;

  repeat

      i:=i+1;   {перейти до наступного запису}

      with directory[i] do

      begin    {ввести дані}

         write(‘name: ’);   readln(user_name);

         write(‘address: ’); readln(address);

         write(‘tel: ’); readln(phone);

      end;

      writeln(‘continue? y/n’);

      key:=readkey;

  until (key=’n’)or(key=’N’);

  number:=i;    {запам’ятати кількість записів}

end;

{===================виведення масиву===================}

procedure print;

var i:integer;

begin

  writeln(‘—User name-------address---------telephone-------’);

  for i:=1 to number do

  begin

    with directory[i] do

    begin

      write(‘   ’, user_name);

      write(‘   ’,address);

      write(‘   ’,phone);

   end;

   writeln;

 end;

end;

{==========сортування масиву записів за алфавітом============}

procedure sort;

var tmp:data;

   i,j:integer;

begin

  for i:=1 to number-1 do

    for j:=i+1 to number do

      begin

        if directory[i], user_name>directory[j].user_name then

                               begin

                                 tmp:=directory[i];

                                 directory[i]:=diredtory[j];

                                 directory[j]:=tmp;

                               end;

           end;

end;

{==============бінарний пошук запису у масиві==============}

procedure BinSearch(left, right:integer);

begin

  if left>right then

      flag:=false

 else

 begin

   middle:=(left+right) div 2;

   if name=directory[middle]. user_name then

      flag:=true

   else if name<directory[middle]. user_name then

              BinSearch(left, middle-1)

         else BinSearch(middle+1,right);

   end;

end;

{=================головна програма================}

begin

   writeln(‘telephone directory’);

   create;

   writeln(‘array of input records’);

   print;

   sort;

   writeln(‘array of records after sort’);

   print;

   repeat  {повторювати пошук, доки не натиснуто клавішу Esc}

     write(‘enter name for search: ’);

     readln(name);

     BinSearch(1,number);

     with directory[middle] do

     if flag then

          writeln(‘item=’,middle, ‘user name->’, user_name, ‘phone->’, phone)

      else writeln(‘record not found’);

    writeln(‘press ESC for finish and any key to continue’);

   until readkey=#27;

end.

5. Записи з варіантами

Дані структурованого типу запису, який було розглянуто у попередньому роздлі, складаються з фіксованої кількості компонентів. Фіксованість структури записів обмежує область їх застосування: такі записи можуть зберігати лише однотипні набори даних. Тому в мові Раsсаl є різновид записів, що об'єднують довільну кількість компонентів. Припустимо, треба створити масив записів з інформацією про викладачів і студентів навчальних закладів. Для викладачів суттевими характеристиками є науковий ступінь, кількість наукових праць, дисципліни, що вони їх викладають, тошо. Для студента суттєвими ознаками є середній бал, форма навчання (денна або заочна) і т. ін. Водночас викладач і студент мають спільні характеристики, такі як прізвище та плата за роботу (заробітна плата або стипендія). Отже, запис з інформацією про учасника навчального процесу матиме фіксовану та варіантну частини. Такий запис иазивається записом із варіантами. Доступ до полів варіантної частини здійснюється за певних умов. Запис містить спеціальне пале ознаки, і його значення вказує, які поля варіантної частини є активними. Оголошення запису з варіантами має такий синтаксис:

type <ім’я типу>=record

                              <фіксована частина>;

                              <варіантна частина>;

                          end;

Фіксовану частину оголошують у звичайний спосіб, як перелік полів та їх типів. Варіантна частина формується за допомогою оператора саsе. Якщо він знаходиться у середині запису, то називається оператором варіанта. У ньому зазначається ім’я та тип поля ознаки, а також міститься перелік наборів полів. Кожен набір полів супроводжується деяким значенням, константою вибору. Якщо значення поля ознаки дорівнює деякій константі вибору, активізується певний набір полів. Наведемо синтаксис оголошення варіантної частини запису:

case <ім’я поля ознаки> :<тип> of

   <константа вибору1>:(<список полів>);

   <константа вибору2>:(<список полів>);

     …

end.

Список полів – це перелік розділених символами крапки з комою записів вигляду <ім’я поля>:<тип>.

Приклад 8.5

Оголосимо запис person, що містить відомості про викладача або студента, та зобразимо схематитчно його структуру (рис. 8.3). У цьому записі поля name та finance становитимуть фіксовану частину, а поля - degree, number, mark, form - варіантну. Поле tag буде полем ознаки.

type person=record

           FIO:string;    {прізвище викладача або студента}

           finance:real    {заробітна плата або стипендія}

           case tag: (teacher, student) of {данні про викладача: }

           teacher: (degree:string;  {наукавий ступінь викладача}

                          number:integer);  {кількість наукових праць}

                                                      {дані про студента: }

           student: (mark:real;   {середній бал успішності}

                           form:string);  {форма навчання студента}

end.

Оголошення записів із варіантами має відповідати певним сннтаксичним правилам:

запис може мати тільки один оператор варіанта саsе;

варіантні компоненти вказують після фіксованої частини запису;

варіантна частина може мати довільну кількість варіантів (альтернатив);

слово end завершує оголошення всього типу, а не лише його варіантної частини;

компоненти кожного варіанта записуються у круглих дужках;

усі ідентифікатори полів усередині одного запису мають бути унікальними;

тип поля ознаки для вибору варианта з варзантної частини має бути перелічуванним;

константа вибору може дорівнювати лише значенням, які мають тип поля ознаки.

      Наступний приклад демонструє використання записів із варіантами.

Приклад 8.6

Розглянемо задачу створення журналу облику викладачів і студентів. Про викладача є ткі відомості: прізвище, науковий ступінь, посадовий оклад і кількість наукових працъ, а про студента — такі: прізвище, середній бал, форма навчання (денна або заочна) і розмір стипендії. Необхідно ]ініціалізувати список викладачів і студентів та вивести дані про тих людей, дохід яких (посадовий оклад або стипендія) перевищує заданий рівень.

Відомості про викладачів і студентів подано у вигляді масиву записів. Оскілки викладачі та студенти мають різні реквізити, то слід використовувати записи з варіантами. Фіксована частина запису має містити спільні для студента та викладача характеристики, тобто прізвище та доход. Інші характеристики відображатимуться полями варіантної частини запису. У процедурах введення та виведення даних використаємо значення поля ознаки для активізації потрібного варіанта запису. Введення значення і активізує варіантну частину запису викладача, значения 2 — запису студента.

Сформулъовану вище задачу розв'язано у програмі ех8_2. Пропонуємо читачеві доповнити цю програму процедурами визначення викладачів із найбільшою кількістю наукових праць і пошуку найкращих студентів.

progrem ex8_2;

user crt;

type person=record

            name:string;       {прізвищє викладача або студента}

            revenue:integer;  {заробітна плата або стипендія}

            case tag: (teacher, student) of

              teacher: (degree:string; number:integer);

              student: (mark:integer; form:string);

         end;

var

list:array [1..10] of person  {список викладачів і студентів}

  i:integer;                           {індекс компонентів масиву}

  level:integer;                    {рівень доходу}

{==========введення масиву викладчів і студентів============}

procedure Input;

var sing:integer;       {ознака категорії людини}

       ch:char;            {ознака завершення циклу}

begin

 clrscr;

 i:=0;                  {лічильник елементів масиву записів}

 repeat

     i:=i+1;       {ввести наступний запис}

     with list[i] do

      begin

        write(‘input type of person: 1-teacher, 2-student ’);

        readln(sing);         {ввести ознаку об’єкта}

        if sing=1 then tag:=teacher else tag:=student;

        case tag of

          teacher:begin         {ввести данні про викладача}

             write(‘name ’): readln(name);

             write(‘scientific degree ’); readln(degree);

             write(‘number of scientific works ’);

             readln(number);

             write(‘revenue ’);readln(revenue);

          end;

         student:begin         {ввести дані про студента}

             write(‘name ’); readln(name);

             write(‘revenue ’); readln(revenue);

             write(‘average mark ’); readln(mark);

             write(‘form of education ’); readln(form);

           end;

         end;                                      {end of case}

       end;                                        {end of with}

       writeln(‘continue? y/n’);

       ch:=readkey;

     until ch=’n’;              {натиснути ‘n’ для завершення введення}

     write(‘enter revenue level ’);

     readln(level);                        {введення рівня доходу}

   end;                                         {end of procedure}

{=========ввести масив викладачів і студентів================}

procedure Output;

var j:integer;

begin

  for j:=1 to i do

    with list[j] do

      if revenue>level then

        case tag of

           teacher: begin

                          writeln(‘teacher :’,name,’ ‘,degree,’ ‘,number,’ ‘,revenue);

                          readln;

                        end;

           student: begin

                           writeln(‘student :’,name,’ ‘,revenue,’ ‘,mark,’ ‘,form);

                           readln;

                        end;

            end;                            {end of case}

end;                                         {end of procedure}

{==================головна програма====================}

begin

   clrscr;

   Input;

   Output;

   readln;

end.

Контрольні питання

1. Записи

2. Запис та його оголошення

3. Доступ до компонентів та операції над записами

4. Масиви записів

5. Записи з варіантами


 

А также другие работы, которые могут Вас заинтересовать

38391. ИСПОЛЬЗОВАНИЕ ИНВЕСТИЦИЙ 64 KB
  Стадии проектирования Разработка и реализация инвестиционного проекта в области реальных инвестиций представляет собой длительный процесс охватывающий работы от идеи внедрения инвестиционного проекта до его эксплуатации. Комплекс работ по подготовке и техникоэкономическому обоснованию целесообразности проекта как правило называют прединвестиционной фазой. Предварительное техникоэкономическое обоснование целесообразности проекта. Разработка технико экономического обоснования проекта.
38393. Теорія держави і права 303 KB
  Поняття і особливості методології теорії права і держави Метод теорії держави і права це сукупність логічних прийомів і конкретних засобів пізнання загальних і основних закономірностей виникнення розвитку і функціонування держави і права. Методи науки теорії держави і права поділяються на загальні окремі конкретні і спеціальні. Загальним методом теорії права і держави як і всіх суспільних наук є метод філософської діалектики. Він полягає у підході до вивчення держави і права який ґрунтується на загальних закономірних зв'язках розвитку...
38395. Історія екогноміки 397.5 KB
  Метою вивчення Історії економічних учень“ є: поглиблення і розширення знань з економічної теорії; економічної і загальної культури фахівців з економіки; формування теоретичної тази бази для аналізу проблем сучасної економічної політики; всі відповіді правильні. Маркса: Злиденність філософіїâ€; Теорії додаткової вартостіâ€; Критика політичної економіїâ€; Критика Готської програмиâ€. Засновником теорії активного торговельного балансу був: а Б. Маркса належать: а дослідження переважно сфери матеріального виробництва;...
38396. ІСТОРІЯ ЕКОНОМІЧНИХ УЧЕНЬ ЯК НАУКА. СТАНОВЛЕННЯ ЕКОНОМІЧНОЇ ДУМКИ 293.5 KB
  Автором теорії утримання яка започаткувала розгляд витрат як альтернативних був: а Т. Автором теорії додаткової вартості був: а А. Автором теорії абсолютної земельної ренти був: а В. Автором суб’єктивнопсихологічної теорії проценту був: а К.
38399. Основи міжнародного морського права 633 KB
  Сучасне міжнародне морське право — це галузь міжнародного права, що регулює дослідження і використання просторів Світового океану, його дна і ресурсів у мирних цілях, а також польоти літальних апаратів у повітряному просторі над Світовим океаном.