- •Глава 6
- •6.1. Понятие структурного типа
- •6.2. Регулярные типы (массивы)
- •6.3. Строковый тип
- •6.4. Комбинированные типы (записи)
- •6.4.1. Определение типа "запись"
- •6.4.2. Записи с вариантами
- •6.4.3. Оператор присоединения
- •6.5. Множественные типы
- •6.6. Файловые типы
- •6.7. Текстовые файлы
- •6.7.1. Определение текстового файла
- •6.7.2. Ввод числовых данных из текстовых файлов
- •6.7.3. Вывод числовых данных в текстовый файл
- •6.8. Ссылочные типы
- •6.8.1. Динамические переменные
- •6.8.2. Линейные списки
- •6.9. Типизированные константы
6.4. Комбинированные типы (записи)
6.4.1. Определение типа "запись"
Структура записи содержит фиксированное число компонент, называ-емых полями. Каждое поле имеет свое имя.
Тип "запись" определяется следующим образом: TYPE typnam = RECORD NP1 : T1; ...... NPn : Tn END , где typnam - имя типа "запись", NP1,...,NPn - имена полей, T1,...,Tn - типы .
Доступ к компонентам записи осуществляется по имени поля, которое через точку записывается после имени переменной (сравните: доступ к компонентам массива - по индексу).
Пример описания типа "запись":
TYPE complex = RECORD re : real; im : real END; VAR a : complex; BEGIN a.re:=3.223; a.im:=6.12; ..... Здесь complex - имя типа; re, im - имена полей.
Пример 6.4.1. Пусть данные о студенте содержат следующие сведе-ния: фамилию, год рождения, пол. Задание - в тексте программы . PROGRAM Stud; CONST n=25;
TYPE student=RECORD
fam : STRING[20];
gr : integer;
pol : char
END;
VAR db : student; { Один объект типа student }
grup : ARRAY[1..n] OF student;
k,m : integer;
BEGIN { Ввести данные о группе студентов }
FOR k:=1 TO n DO
BEGIN
WriteLn('Студент номер ', k);
Write('Фамилия : '); ReadLn(grup[k].fam);
Write('Год рождения : '); ReadLn(grup[k].gr);
Write('Пол : '); ReadLn(grup[k].pol);
END;
{ Распечатать данные обо всех студентках }
WriteLn;
WriteLn('Данные обо всех студентках : ');
FOR k:=1 TO n DO
IF grup[k].pol = 'ж' THEN
WriteLn(grup[k].fam, grup[k].gr:7);
{Подсчитать количество студентов, родившихся в 1979 году}
m:=0;
FOR k:=1 TO n DO
IF grup[k].gr = 1979 THEN m:=m+1;
WriteLn;
WriteLn('Количество студентов 1979 года = ', m);
{ Студента с фамилией Иванов поместить в позицию 7 }
k:=0;
REPEAT
k:=k+1
UNTIL (grup[k].fam = 'Иванов') OR (k=n);
IF grup[k].fam = 'Иванов' THEN grup[7]:=grup[k]; { ....... и т. д. ....... }
END.
6.4.2. Записи с вариантами
Язык Паскаль позволяет создавать записи с полями переменной структуры - так называемые записи с вариантами.
Пример 6.4.2. Данные о студенте содержат фамилию, пол, а для юношей - еще отношение к воинской службе и год рождения.(Задание - в тексте программы ).
PROGRAM Recvar;
CONST n=25;
TYPE student = RECORD
fam : STRING[20];
CASE pol:char OF
'м': (vob:Boolean; gr:integer);
'ж': ()
END;
VAR grup : ARRAY[1..n] OF student;
k : integer;
v : char;
BEGIN
{ Ввод данных о группе студентов }
FOR k:=1 TO n DO
BEGIN
WriteLn('Данные о студенте', k:3);
Write('Фамилия: '); ReadLn(grup[k].fam);
Write('Пол: '); ReadLn(grup[k].pol);
IF grup[k].pol = 'м' THEN
BEGIN
Write('Военнообязанный (д/н):');ReadLn(v);
grup[k].vob := v='д';
Write('Год рождения:' ); ReadLn(grup[k].gr)
END
END;
{ Отпечатать фамилии всех военнообязанных}
WriteLn; WriteLn('Военнообязанные:');
FOR k:=1 TO n DO
IF grup[k].pol='м' THEN
IF grup[k].vob THEN WriteLn(grup[k].fam)
END.
Описание типа student содержит фиксированную часть (поля fam, pol) и вариантную: для юношей поля vob, gr, для девушек - пусто. (рис. 6.3)
Иванов
Петрова
м
ж
TRUE
1980
Рис.6.3.
Информация о двух студентах
Вариантная часть следует за служебными словами CASE-OF, между которыми располагается дискриминант - последнее поле фиксированной части. В нашем примере - это pol:char . Каждая альтернатива вариантной части содержит список меток (константы типа дискриминанта), за которым в скобках следует список полей. Для юношей это
'м': (vob:Boolean; gr:integer) ,
для девушек
'ж': () .
Типы полей в списках полей должны задаваться только идентифика-торами.
В определении комбинированного типа может быть только одна вари-антная часть, которая располагается в конце записи.
Любой вариант в свою очередь может содержать одну вариантную часть, подчиняющуюся приведенным выше правилам.
Имена полей в фиксированной и вариантной частях одного уровня должны быть различными, для разных уровней - могут совпадать.
Для всех альтернатив вариантной части отводится единая область памяти, причем по самому большому варианту.
Дискриминантом вариантной части может быть не только поле записи, но и имя упорядоченного типа.
Пример 6.4.3. Имеется вещественное число Распечатать его по битам.
PROGRAM Realbit;
TYPE arrbyt = ARRAY[1..6] OF byte;
chis = RECORD
CASE integer OF
0 : (rea : real);
1 : (byt : arrbyt)
END;
VAR k,m : integer;
b : byte;
c : ARRAY[1..8] of byte;
a : chis;
BEGIN
Write('Вещественное число : '); ReadLn(a.rea);
FOR k:=1 TO 6 DO
BEGIN
b:=a.byt[k];
FOR m:=1 TO 8 DO
BEGIN
c[m]:=b MOD 2;
b:=b DIV 2
END;
FOR m:=8 DOWNTO 1 DO Write(c[m]);
Write(' ');
END;
WriteLn
END.
В рассматриваемом случае метки не несут никакой алгоритмической нагрузки, а лишь нумеруют поля.