КОМБИНИРОВАННЫЕ ТИПЫ. ЗАПИСИ
     Запись – структура данных, состоящая из  фиксированного числа компонент, называемых полями каждая из  которых может иметь свой тип.  
     Структурированные типы в отличие от  скалярных состоят из компонент.
     Регулярные типы – фиксированное  число однотипных компонент.
     Комбинированные  типы– фиксированное  число компонент различных типов.
     Записи  позволяют в компактной форме описывать различные объекты (списки, каталоги,  картотеки, таблицы, ведомости и т.д.).
  Рассмотрим  способы описания, ввода/вывода и обработки записей.
 
Описание записей в Паскале
     При использовании записей они д.б. описаны  с использованием раздела описания либо непосредственно в разделе описания переменных
  Запись имеет следующую структуру:
IZ = RECORD                         Где:  IZ – имя  типа записи;
                IK1 : T1;                                IK – имя поля (компоненты);
                 IK2 : T2;                                 T   - тип компоненты, м.б. любой стан-
                  . . .                                                дартный либо предварительно
                 IKN :TN;                                       определенный (кроме файлового);
             END;                                             RECORD – запись;
                                                                  RECORD-END – операторные скобки.
 
Пример описания записи
       Const  n=25;
         Type   Date = Record
                                     Year       : integer;    {Год}
                                      Month   : 1..12;        {Число}
                                      Day        :  1..31;        {Месяц}
                                 End;
                Student = Record
                                     FIO        : String[15]; {ФИО}
                                     Dr           : Date;          {Дата рождения}
                                     Str          : String[20]; {Страна}
                          b1,b2,b3,b4,b5  : 2..5;            {Поле оценок}
                                 End;
                       Vec = array[1..n] of  Student;
  
  Var    EMS_43a, EMS_43a,  EMS_43a    :Vec;
 
Порядок следования полей в записи не  имеет значения.
  Поле может иметь несколько имен, при этом  они разделяются запятыми.
  Для наглядности поля следует располагать  на отдельных строках и снабжать комментариями.
  Запись может содержать вариантную часть.  Например, для иностранных студентов можно указать страну.
    Type x=(Yes, No);
                 Student = Record
                                       FIO        : String[25]; {ФИО}
                                       Mark      : 2..5;            {Оценки}
                                       Variant   :x;
                                        Case x of
                                                Yes  : (Str  : String[20]); {Страна}
                                                No   :  (      );
                                End; 
 
Обработка записей в Паскале
     При обработке записей все действия  выполняются над полями записи в соответствии с их типами. Набор операций,  процедур и функций определяется типом поля. Для записи в целом м.б. использован  только оператор присваивания. Запись можно передавать в качестве параметров  в  процедуру и функцию.
  Для обращения к полям записи используются  составные имена. 
Составное имя – совокупность имени переменной типа запись и имен полей  разделенных точкой.
Например:
EMS_43a[1].FIO  :=’Антонов’;                        
  EMS_43a[1].Dr.Day :=13;
  EMS_43a[1].Dr. Month :=1;
  EMS_43a[1].Dr. Year  :=1986;
 
 
Оператор присоединения в Паскале
     Оператор присоединения позволяет упростить  обращение к элементам записи и имеет следующий формат записи:
  With   <Имя>  do 
                                          OP;
  Где   With     - с;
               <Имя>  - имя  записи (простое или составное);
                  do        - делать;
                  OP       - оператор (простой или составной);
 
Вввод / вывод записей в Паскале
     При   вводе/выводе записей используются отдельные поля записи
For i:=1  to n do Read (EMS_43a[i].FIO, EMS_43a[i].Str)
  При использовании оператора  присоединения
        For i:=1 to n  do
              With  EMS_43a[i] do
                   Begin
                        Read (FIO);
                        Read (Str);
                    End;
 
Примеры программ
Пример 18.1. В файле sp_gr.txt  содержатся результаты сдачи сессии студентами   группы КИТ-23а.   Составить  программу анализа результатов сдачи сессии.
  Вычислить средний бал каждого студента,  результат вывести на экран и в файл rez.txt.На экран вывести также средний балл каждого студента по  первому предмету в списке и общий средний балл группы.
 
Исходный файл sp_gr.txt
Антонов И.И.   5 5  4 3 4
  Андеев И.Т.    4 5  3 4 2
  Иванов Н.Р.    5 5  4 2 4
  Петpов П.И.    3 4  3 2 5
  Агапов Е.И.    5 4  3 5 2
  Токаев П.И.    4 5  2 4 4
  Павлов О.О.    3 3  3 4 5
  Мщисеев Н.Т.   5 4  3 4 5
  Сидоров Н.Р.   5 4  3 2 5
  Егоров Н.Р.    5 3  4 3 5 
 
Текст программы (srbal.pas) 
Program srbal;
  {Программа  анализа успеваемости студентов группы}
  Uses crt;
  Const n=10;             {Число студентов}
  Type st=Record
  fam:string[15];
  b1,b2,b3,b4,b5:2..5;
  End;
  vec = array[1..n] of st;
  Var
  KIT_23b          :vec;
  sb1,sbo,sb       :real;
  i                :byte;
  f1,f2            :text;
  Begin
  Clrscr;
  Assign(f1,'sp_gr.txt');  Reset(f1);
  Assign(f2,'rez.txt');    Rewrite(f2);
  sbo:=0;   sb1:=0;
  For i:=1 to n do
  Begin
  sb:=0;
  With KIT_23b[i] do
  Begin
  Read(f1,fam);  Write(fam); Write(f2,fam);
  Readln(f1,b1,b2,b3,b4,b5);
  sb:=sb+(b1+b2+b3+b4+b5)/5;
  Writeln(sb:4:2);  Writeln(f2,sb:4:2);
  sb1:=sb1+b1/n;
  End;
  sbo:=sbo+sb/n;
  End;
  Writeln;
  Writeln('sbo=',sbo:4:2,'  ':10,'sb1=',sb1:4:2);
  Close(f1);   Close(f2);
End.
 
Результаты  работы программы:
  (экран)                                                                       (файл rez.txt)
  Антонов И.И.        4.20
    Андеев И.Т.     3.60
    Иванов Н.Р.     4.00
    Петpов П.И.     3.40
    Агапов Е.И.     3.80
    Токаев П.И.     3.80
    Павлов О.О.     3.60
    Мщисеев Н.Т.       4.20
    Сидоров Н.Р.        3.80
    Егоров Н.Р.      4.00
 
  
Антонов  И.И.  4.20
Андеев  И.Т.     3.60
Иванов  Н.Р.     4.00
Петpов  П.И.    3.40
Агапов  Е.И.     3.80
Токаев  П.И.     3.80
Павлов  О.О.    3.60
Мщисеев  Н.Т. 4.20
Сидоров  Н.Р.   3.80
Егоров  Н.Р.      4.00
sbo=3.84          sb1=4.40
      
          Пример 18.2.   Составить список студентов  группы КИТ-23а имеющих право на получение  стипендии (средний бал не ниже  4.0).  Средний бал каждого студента по результатам сессии приведен в файле rez.txt (см. пример №1).
 
Текст программы
  Program STIP;
  {Программа  анализа упеваемости}
  uses CRT;
  const n=10;
  Type st=Record
  FIO: string[15];
  SB:  real;
  end;
  vec = array [1..n] of st;
  Var sp,sp1     :vec;
  i,k,kst    :integer;
  f          :text;
  Procedure VVod (var st:vec);
  {Ввод сиска студентов}
  Begin
  For i:= 1 to n do readln  (f,st[i].FIO,st[i].SB);
  End;
  Procedure Out(st:vec;var st1:vec; var ks:integer);
  { Список студентов на стипендию  с баллом выше 4,5 }
  Begin
  k:=1;
  for i:=1 to n do if st[i].sb >4.5  then
  begin
  st1[k]:=st[i];  ks:=k; k:=k+1;
  end;
  end;
  Begin
  assign (f,'inp2.txt'); reset (f);
  clrscr;
  Writeln('Исходный массив записей');
  Writeln;
  VVod (sp);   Out(sp,sp1,kst);
  For i:=1 to n do 
  Writeln (sp[i].FIO,' ', sp[i].SB:4:2);
  Writeln ('Результат:':30);
  Writeln('Список  студентов на стипендию с баллом выше 4,5 ');
  For k:=1 to kst do Writeln  (sp1[k].FIO,' ',sp1[k].SB:4:2);
  Writeln ('Количество студентов с  баллом выше 4,5 :',kst);
  Writeln;
  Readln;
End.
 
Результаты  работы программы:
Исходный  массив записей
Антонов  И.И.    4.20
  Андеев  И.Т.     3.60
  Иванов  Н.Р.     4.00
  Петpов  П.И.     3.40
  Агапов  Е.И.     3.80
  Токаев  П.И.     3.80
  Павлов  О.О.     3.60
  Мщисеев  Н.Т.    4.20
  Сидоров  Н.Р.    3.80
  Егоров  Н.Р.     4.00
  Результат:
  Список  студентов на стипендию  с баллом не ниже  4
  Антонов  И.И.    4.20
  Иванов  Н.Р.     4.00
  Мщисеев  Н.Т.    4.20
  Егоров  Н.Р.     4.00
  Количество  студентов с баллом не ниже 4 равно :4
 
Пример 18.3. Составить  список студентов  группы КИТ-23а имеющих  право на голосование (с датой рождения до 30.10.2004 г.).
 
Исходный файл sp_gr.txt
Антонов И.И.   05  12 1986
  Андеев И.Т.     14 05 1985
  Иванов Н.Р.     15 12  1985
  Петpов П.И.     31 10  1986
  Агапов Е.И.     11 04  1985
  Токаев П.И.     14 05  1986
  Павлов О.О.     30 10  1986
  Мщисеев Н.Т.   22  09 1985
  Сидоров Н.Р.    29 12  1985
Егоров Н.Р.      17 10  1985 
 
Текст программы
Program GOLOS;
  {Сотавление  списка для голосования. Выборы 31.10.2004 г.}
  uses CRT;
  const n=10;
  Type
  Date=Record
  Day   :1..31;
  Month :1..12;
  Year   :1980..1987;
  end;
  st=Record
  FIO: string[15];
  DR : Date;
  end;
  vec = array [1..n] of st;
  Var sp,sp1     :vec;
  i,kvo,k    :byte;
  f          :text;
  Procedure VVod (var st:vec);
  {Ввод списка студентов из файла и  вывод на экран}
  Begin
  For i:= 1 to n do
  With st[i] do
  begin
  readln  (f,FIO,DR.Day,DR.Month,DR.Year);
  Writeln(FIO,DR.Day:4,DR.Month:4,DR.Year:6);
  end;
  End;
  Procedure Out (st:vec;var st1:vec; Var  kn:byte);
  { Формирование списка студентов для  голосования}
  Begin
  k:=1;
  for i:=1 to n do if
  (st[i].DR.Year<=1986)and
  (st[i].DR.Month<=10)and
  (st[i].DR.Day<=30) then
  begin
  st1[k]:=st[i]; kn:=k; k:=k+1;
  End;
  End;
  Begin
  assign (f,'sp_gr1.txt'); reset (f);
  clrscr;
  Writeln('Исходный массив записей:':30);
  Writeln;
  VVod (sp); Out(sp,sp1,kvo);
  Writeln ('Результат:':30);
  Writeln ('Спиок  студентов для голосования:');
  For k:= 1 to kvo do
  With sp1[k] do  Writeln(FIO,DR.Day:4,DR.Month:4,DR.Year:6);
  Writeln ('Число студентов в  списке=> ',kvo);
  Readln;
  End.
 
Результаты  работы программы:
Исходный  массив записей:
Антонов  И.И.      5  12   1986
  Андеев  И.Т.      14   5   1985
  Иванов  Н.Р.      15  12   1985
  Петpов  П.И.      31  10   1986
  Агапов  Е.И.      11   4   1985
  Токаев  П.И.      14   5   1986
  Павлов  О.О.      30  10   1986
  Мщисеев  Н.Т.    22   9   1985
  Сидоров  Н.Р.     29  12   1985
  Егоров  Н.Р.       17   10  1985
  Результат:
  Спиок  студентов для голосования:
  Андеев  И.Т.      14   5   1985
  Агапов  Е.И.      11   4   1985
  Токаев  П.И.      14   5   1986
  Павлов  О.О.      30  10   1986
  Мщисеев  Н.Т.   22    9  1985
  Егоров  Н.Р.      17  10   1985
Число  студентов в списке=> 6