Лекция 7. Сложные типы данных.

 

1.     Массивы.

2.     Строки.

3.     Файловый тип данных.

4.     Множества

5.     Записи

 

1.     Массивы.

Массивы представляют собой ограниченную упорядоченную совокупность однотипных величин.  Каждая отдельная величина называется компонентой

массива. Тип   компонент может быть любым,  принятым в языке ПАСКАЛЬ, кроме файлового типа. Тип компонент называется базовым типом.

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

       A[5]     S[k+1]     B[3,5].

 В качестве индекса может быть использовано выражение. Тип индексов может быть только интервальным или перечисляемым.   Действительный  и

целый типы недопустимы.  Индексы интервального типа, для которого базовым является целый тип,  могут принимать отрицательные,  нулевое  и

положительные значения.{}

  В операторной части программы один массив может быть присвоен другому, если их типы идентичны, например:

    R1:=Z.

   Для ввода или вывода массива в список ввода или вывода помещается переменная с индексом,  а операторы ввода или  вывода  выполняются  в цикле.

   Первый индекс  определяет  номер  строки, второй - номер столбца.

Двумерные массивы хранятся в памяти ЭВМ по строкам.

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

   Первый способ - с использованием типизированных констант,   например:

   type Dim10= Array[1..10] of Real;

   const

    raM10: Dim10 = ( 0, 2.1, 4, 5.65, 6.1, 6.7, 7.2, 8, 8.7, 9.3 );

   При инициализации двумерных массивов значения компонент каждого из

входящих в него одномерных массивов записывается в скобках:

   type Dim3x2= Array[1..3,1..2] of Integer;

   const

    iaM3x2: Dim3x2= (  (1, 2)

                                    (3, 4)

                                     (5, 6)  );

   Второй способ инициализации - использование разновидности процедуры FillChar:

 

   FillChar( var V; NBytes: Word; B: Byte );

Эта процедура заполняет участок памяти однобайтовым значением. Например, для обнуления массива A[1..10] of Real можно записать:

   FillChar(A, 40, 0); или FillChar(A, SizeOf(A), 0);

 

Различают одномерные массивы (1 индекс)  и двумерные массивы (2 индекса) – они используются для представления матриц. Массивы относятся к сложным типам и описать их можно как через раздел переменных Var  и через раздел типов Type.

Объявление одномерного массива через раздел Var.

Var  <имя массива>:array [< t> ] of <базовый тип >;

где t  – диапазон изменения индекса у элементов массива;

 <базовый тип> – тип самых элементов массива;

Например:

Var Х: array [1..15] of integer; – одномерный массив из 15 целых чисел.

 

Объявление одномерного массива через раздел Type.

Объявление одномерного массива через раздел Type происходит в два этапа:

1 –й: в разделе типов дается формальное название  всем массивам одного базового типа и одинаковой размерности;

2 –й: в разделе переменных указывается, что заданный массив такового же типа, что указан на первом этапе;

Type <имя типа> = array [< t>] of <базовый тип >;

Var  <имя массива>:<имя типа>;

Например, описание того же одномерного массив из 15 целых чисел через раздел типов:

Type  vek = array [1..15] of integer;

Var  X: vek;

 

 При описании двумерного массива в квадратных скобках указываются два  диапазона:  изменения индекса строк и индекса столбцов. Например:

У: array [1..5,1..4] of real; – двумерный массив, состоящий из пяти строк и четырех столбцов( из 20 вещественных чисел).

 

2. СТРОКИ

 

   Особое место в языке ПАСКАЛЬ занимают массивы символов.  Стандартный ПАСКАЛЬ допускает два способа хранения символьных массивов в  памяти ЭВМ: распакованный и упакованный. Распакованные массивы символов хранятся в памяти ЭВМ по одному символу в машинном слове, упакованные - по одному символу в байте. При описании упакованного массива символов используют служебное слово PACKED, например:

            var   MAS: Packed Array[1..20] of Char;

Описание распакованного массива символов имеет вид:

            var   M: Array[1..20] of char;

   Для преобразования символьного массива из  распакованной  формы  в упакованную и наоборот,  из упакованной в распакованную,  в язык ПАСКАЛЬ введены две стандартные функции Pack, UnPack.

   Упакованный массив символов образует символьную строку. Символьная

строка может быть либо строковой константой, либо строковой  переменной. Строковая константа, или строка, представляет собой совокупность символов, заключенную  в апострофы.  Строка - это элементарная  конструкция языка ПАСКАЛЬ. Строковые константы могут входить в состав выражений. Как  и числовые константы,  они могут быть описаны в разделе

описания констант.

   Строковые переменные - это одномерные упакованные  массивы  символов, для описания которых в TURBO PASCAL введен тип String.

   Например, если строка содержит до 30 символов,  ее тип будет определен как

    type   s= String[30];

   Длина строки не может содержать более, чем 255 символов.

   В TURBO PASCAL определено понятие строки переменной длины,  в этом

случае ее описание задается как

 

    type  s= String;

 

   Тип String без указания длины совместим со всеми типами строк.

   Особенностью строковых переменных является то, что к ним можно обращаться как к скалярным переменным, так и к массивам. Во втором случае применяется конструкция "переменная с индексом", что обеспечивает

доступ к   отдельным символам строки.  При этом нижняя граница индекса равна 1. Отдельный символ строки совместим с типом Char.

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

   Для строк определены операции присваивания, слияния (конкатенации)

и сравнения.

   Для сравнения строк применяются все операции отношения.  Сравнение

строк происходит посимвольно,  начиная с первого символа. Строки равны, если имеют одинаковую длину и посимвольно эквивалентны.

   Строки могут быть элементами списка ввода - вывода, при этом записывается имя строки без индекса.

   При вводе  строковых переменных количество вводимых символов может

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

символы отбрасываются.

   Инициализация строк может производиться как с помощью типизированных констант:

   const sName: String[9]= 'IBM PC/AT';

так и с использованием второй разновидности функции FillChar:

   FillChar( var V; NBytes: Word; C: Char );

например:

   FillChar(A, SizeOf(A), '0');

   Для работы  со  строками в TURBO PASCAL включены процедуры и функции, которые обеспечивают редактирование и преобразование строк.

 

3.Файловый тип данных

До сих пор, при решении каких – то задач,  данные значения параметров вводились  с клавиатуры, а результаты выполнения программы выводились на экран. Поэтому не исходные данные, ни результаты не сохранялись. А при каждом запуске программы, приходилось заново вводить исходные данные. Оказалось, что на языке Паскаль есть возможность создать из исходных данных  внешний файл, и каждый раз по надобности, читать их оттуда. Такой же внешний файл можно создать и для результатов выполнения программы тоже.

 В языке Паскаль файл представляет собой последовательность элементов одного типа. И каждый элемент файла становится доступным только после перебора предыдущих элементов. При работе с файлами используются стандартные функции учета конца файла EOF(f)  или конца строки в файле EOLN(f).

Объявление файловой переменной в разделе описания переменных имеет вид:

Var  <имя файла>:file of <базовый тип>;

Например, 

Var  f1 :file of real; - описание файла вещественных чисел.

Var  f2 : file of char; - описание файла символьного типа.

или

Var  f2: text; - описание файла символьного типа.

Текстовые файлы состоят из символьных строк, строки могут иметь различную длину. Для описания текстовых файлов используется служебное слово text.

Для установления связи между файловой переменной и файлом на диске имеется стандартная процедура assign.

Assign(<имя файловой переменной>,'<имя файла на диске>');

Например: assign (f1,'primer.dat');

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

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

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

Для чтения из файла необходимо открыть файл для чтения посредством процедуры:

reset(<имя файловой переменной>);

Собственно чтение данных из файла выполняется процедурой:

read(<имя файловой переменной>,<имя переменной>);

Согласно этой записи данные вводятся из файла, хранящегося на диске.

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

rewrite (<имя файловой пременной>);

Для добавления  данных в существующий файл используется процедура:

append(<имя файловой пременной>);

Собственно запись данных в файл выполняется процедурой:

write(<имя файловой переменной>,<значение>);

Согласно этой записи данные записываются в файл.

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

close(<имя файловой переменной>).

 

4. МНОЖЕСТВА

 

   Понятие множества в языке ПАСКАЛЬ основывается  на  математическом

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

   Множественный тип  описывается  с  помощью  служебных слов Set of,

например:

         type  M= Set of B;

Здесь М - множественный тип, В - базовый тип.

   Пример описания переменной множественного типа:

         type

             M= Set of 'A'..'D';

         var

            MS: M;

   Принадлежность переменных к множественному типу может быть определена прямо в разделе описания переменных:

         var

            C: Set of 0..7;

   Константы множественного  типа  записываются  в виде заключенной в квадратные скобки последовательности элементов или интервалов базового типа, разделенных запятыми, например:

         ['A', 'C']    [0, 2, 7]    [3, 7, 11..14].

Константа вида

         [ ]

означает пустое подмножество.

   Множество включает в себя набор элементов базового типа, все под множества данного множества, а также пустое подмножество. Если базовый

тип, на котором строится множество, имеет К элементов, то число подмножеств, входящих в это множество, равно 2 в степени К. Пусть имеется

переменная Р. интервального типа:

         var P: 1..3;

   Эта переменная может принимать три различных значения  -  либо  1,

либо 2, либо 3. Переменная Т множественного типа

         var T: Set of 1..3;

может принимать восемь различных значений:

         [ ]        [1,2]

         [1]        [1,3]

         [2]        [2,3]

         [3]        [1,2,3]

   Порядок перечисления элементов базового типа в константах  безразличен.

   Значение переменной  множественного  типа  может быть задано конструкцией вида [T], где T - переменная базового типа.

   К переменным и константам множественного типа  применимы  операции

присваивания(:=), объединения(+), пересечения(*) и вычитания(-):

         ['A','B'] + ['A','D']      даст  ['A','B','D']

         ['A'] * ['A','B','C']      даст  ['A']

         ['A','B','C'] - ['A','B']  даст  ['C'].

 

   Результат выполнения  этих  операций  есть величина множественного типа.

   К множественным величинам применимы операции: тождественность (=),

нетождественность (<>), содержится  в (<=), содержит (>=).  Результат

выполнения этих операций имеет логический тип, например:

         ['A','B'] = ['A','C']  даст FALSE

         ['A','B'] <> ['A','C'] даст TRUE

         ['B'] <= ['B','C']     даст TRUE

         ['C','D'] >= ['A']     даст FALSE.

   Кроме этих операций для работы с величинами множественного типа  в языке ПАСКАЛЬ используется операция   in проверяющая  принадлежность  элемента  базового типа,  стоящего слева от знака операции,  множеству, стоящему справа от знака операции. Результат выполнения этой операции - булевский.  Операция проверки принадлежности элемента множеству часто используется вместо операций отношения, например:

         A in ['A', 'B'] даст TRUE,

         2 in [1, 3, 6]  даст  FALSE.

   При использовании  в   программах   данных   множественного   типа выполнение операций происходит над битовыми строками данных.  Каждому

значению множественного типа в памяти ЭВМ соответствует один двоичный

разряд. Например, множество

         ['A','B','C','D']

представлено в памяти ЭВМ битовой строкой

         1 1 1 1.

Подмножества этого множества представлены строками:

         ['A','B','D']   1 1 0 1

         ['B','C']       0 1 1 0

         ['D']           0 0 0 1

   Величины  множественного типа не могут быть элементами списка ввода - вывода.

   В каждой  конкретной  реализации транслятора с языка ПАСКАЛЬ количество элементов базового типа,  на котором строится множество, ограничено. В  TURBO PASCAL количество базовых элементов не должно превышать 256.

   Инициализация величин  множественного  типа производится с помощью

типизированных констант:

   const seLit: Set of 'A'..'D'= [];

   Проиллюстрируем применение  данных множественного типа на примере.

   Пример. Составить программу, которая вырабатывает и выводит на экран дисплея наборы случайных чисел для игры в "Спортлото 5 из 36".

   Для заполнения каждой карточки спортлото необходимо получить набор

из пяти псевдослучайных чисел. К этим числам предъявляются два требования:

    -числа должны находиться в диапазоне 1..36;

    -числа не должны повторяться.

    Program Lotto;

     var

         nb, k: Set of 1..36;

         kol, l, i, n: Integer;

     begin

        Randomize;

        WriteLn('ВВЕДИ kol');

        ReadLn(kol);

        nb:=[1..36];

        for i:=1 to kol do

          begin

           k:=[];

           for l:=1 to 5 do

             begin

               repeat

                 n:=Random(36)

               until (n in nb) and not (n in k);

               k:=k+[n];

               Write(n:4)

             end;

           WriteLn

          end

         end.

   

5. ЗАПИСИ

 

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

   Описание записи   в   языке   ПАСКАЛЬ   осуществляется  с  помощью служебного слова RECORD,  вслед за которым описываются компоненты записи. Завершается описание записи служебным словом END.

   Например, записная книжка содержит фамилии,  инициалы и номера телефона, поэтому отдельную строку в записной книжке удобно представить

в виде следующей записи:

 

         type   Row=Record

                     FIO: String[20];

                     TEL: String[7]

                    end;

         var    str: Row;

 

   Описание записей возможно и без использования имени типа,   например:

         var  str: Record

                    FIO: String[20];

                    TEL: String[7]

                   end;

 

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

  

         str.FIO,   str.TEL

 

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

   Обращение к  компонентам записей можно упростить,  если воспользоваться оператором присоединения with.

   Он позволяет заменить составные имена,  характеризующие каждое поле, просто на имена полей, а имя записи определить в операторе присоединения:

  

         with M do OP;

   Здесь М  -  имя  записи,   ОР  - оператор,  простой или составной.

Оператор ОР представляет собой область действия оператора присоединения, в пределах которой можно не использовать составные имена.

   Иногда содержимое отдельной записи зависит от значения  одного  из ее полей.  В языке ПАСКАЛЬ допускается описание записи,  состоящей из общей и вариантной частей.  Вариантная часть задается с помощью конструкции

         case P of,

 

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

Однако вместо указания выполняемого действия, как это делается в операторе варианта,    указываются поля варианта,  заключенные в круглые

скобки. Описание вариантной части завершается служебным словом end.

   Тип поля Р можно указать в заголовке вариантной части, например:

         case P: Integer of

  

   Инициализация записей  осуществляется  с  помощью   типизированных

констант:

      type

     RecType= Record

               x,y: Word;

               ch: Char;

               dim: Array[1..3] of Byte

              end;

  

   const

     Rec: RecType= ( x: 127; y: 255;

                     ch: 'A';

                     dim: (2, 4, 8) );