Записи в Pascal

Записи (Record)

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

type t = record
    id11, id12, …: type1;
    id21, id22, …: type2;
    ……………….
end;

здесь id – идентификаторы полей; type – типы полей; t – имя типа.

Пример. Данные комплексного вида можно описать переменной типа record.

type complex = record
    re, im: real
end;
var c: complex;

здесь complex – имя типа, а c – имя переменной. Переменная c состоит из двух полей: re и im, имеющих один и тот же тип (real). Эти поля переменной c обозначаются как c.re и c.im.

Пример. Даты каких-либо событий можно описать следующим образом:

type date = record
    month: 1..12;
    day: 1..31;
    year: integer
end;
var d: date;

В этом примере описан тип date и переменная d, принадлежащая этому типу.

Переменная d описана как запись, состоящая из трех полей: month, day и year. Каждое поле содержит соответственно данные: целое число в пределах от 1 до 12 (номер месяца), целое число от 1 до 31 (число), целое число (год).

Поле day переменной d записывается как d.day.

Например, чтобы заслать в d дату 12.01.2003, надо выполнить следующие операторы:

d.month := 1;
d.day := 12;
d.year := 2003;

Пример. Вычислить сумму s двух комплексных чисел x = 2 + 7i и y = 6 + 3i (т.е. x, y, s: complex;).

x.re := 2.0; x.im := 7.0;
y.re := 6.0; y.im := 3.0;
s.re := x.re + y.re;
s.im := x.im + y.im;

Запись может быть компонентой других структур. Например, введем тип family (семья: отец, мать, 1-й ребенок, 2-й ребенок):

type family = (father, mother, child1, child2);
var birthday: array[family] of date;

где date – описанная выше запись.

Переменная birthday есть массив, состоящий из записей – дат рождения членов семьи: отца, матери, 1-го ребенка, 2-го ребенка. Каждая дата рождения имеет тип date, который может быть описан в программе.

Для занесения даты рождения, например, mother, достаточно выполнить операторы:

birthday[mother].month := 5;
birthday[mother].day := 1;
birthday[mother].year := 1965;

Сравнение записей с массивами

В то время как массив – объединение компонент одинакового типа, в записи можно объединять компоненты различного типа. Сравните массив и запись:

type
    numb = array[1..4] of integer;
    date = record
        month: 1..12;
        day: 1..31;
        year: integer;
        week: (mo, tu, we, th, fr, sa, su)
    end;
Типы данных: массив и запись

Переменные, определенных выше типов, содержат либо целые массивы, либо целые записи:

var
    m, n: numb;
    one, two: date; 
Переменные типов массив и запись

Присваивание значений элементам массивов и записей также имеет некоторое сходство:

m[1] := 498;
n[3] := 637;
one.day := 25;
one.week := fr;
two.year := 2011;
Присваивание значений переменным типов массив и запись

Следует отметить, что записи сами могут быть элементами массива. Пример массива записей:

var
    daysopen: array[1..10] of date;

Оператор With

Этот оператор используется для удобства работы с переменными типа record (запись).

Общий вид:

with a do st;

здесь a – имя переменной типа record, st – оператор.

В операторе st при ссылках на компоненты записи имя a можно опускать.

Пример. Для занесения даты рождения достаточно выполнить операторы:

with birthday[mother] do begin
    month := 5;
    day := 1;
    year := 1965
end;

Запись с вариантами

Общий вид:

type v = record
    a: type1
    b: type2
    ……
    case n: typen of
        c1:(t11: type11;
            t12: type12; …);
        c2:(t21: type21;
            t22: type22; …);
        ……..
end;
var z: v;

Здесь z – переменная типа v; n – переменная, называемая переключателем; typen – тип переменной n.

Этому же типу должны принадлежать метки c1 и c2. Каждой метке соответствует набор полей t11, …. Эти поля являются компонентами варианта.

Если какой-либо метке c вообще не соответствуют поля, то пишут c…: ( );

Замечания:

  1. Любая запись (record) может иметь только одну вариантную часть (case).
  2. Вариантная часть должна помещаться после постоянной части.
  3. Среди идентификаторов полей не должно быть одинаковых.

Обращение к компоненте z.tij записи z происходит так:

  1. Присваивается соответствующее значение c… переключателю n. В зависимости от значения n переменная z, помимо полей a, b, …, содержит те поля, которые соответствуют той метке c…, с какой совпадает значение n.
  2. Выполняется операция с компонентой z.tij.

Пример. Пусть необходимо собрать следующие сведения о сотрудниках института: фамилию, дату рождения и, если есть семья, то фамилию и дату рождения супруги (супруга).

Эта информация может быть описана, например, записью person.

Пусть переменная типа kind может иметь одно из значений («женат», «холост»).

kind = (married, single);
person = record
    name: string;
    datebirth: date;
    case yesno: kind of 
        married: (name1: string; date1: date);
        single: ()
end;

Здесь name – строка символов; datebirth – запись, содержащая дату рождения; yesno – переключатель типа kind, который может принимать одно из двух значений: married либо single; name1 – строка символов, содержащая фамилию супруга(и); date1 – запись, содержащая дату рождения; single – пустое поле.

Если персона в браке, то будет присутствовать поле married, если нет – поле single. Паскаль допускает вложение вариантов в типе record.

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

Пример.

type
    kind = (married, single);
    date = record
        day: 1..31;
        month: 1..12;
        year: integer;
    end;
    person = record
        name: string;
        datebirth: date;
        case yesno: kind of
            married: (name1: string; date1: date);
            single: ()
    end;
 
var
    p: person;
 
begin
    with p do begin
        yesno := married;
        name := 'panin';
        with datebirth do begin
            day := 14;
            month := 5;
            year := 1962
        end;
        case yesno of
            married: begin
                name1 := 'panina';
                with date1 do begin
                    day := 30;
                    month := 12;
                    year := 1968
                end;
            end;
        end;
    end;
 
    with p do
        write(' ', name);
    with p.datebirth do
        writeln(' ', day, '/', month, '/', year);
    with p do
        write(' ', name1);
    with p.date1 do
        write(' ', day, '/', month, '/', year);
 
readln
end.