Введение

Линейные алгоритмы

Алгоритмы с ветвлением

Алгоритмы с повторением

Одномерный массив (вектор)

Двумерный массив (матрица)

Пользовательские процедуры и функции

Строки

Множества

Записи
маркированный список

справочные материалы

маркированный список

теоретические вопросы

маркированный список

задачи, решения, программы

Файлы

Графика

На главную
              

Записи

Запись - упорядоченный набор значений различных типов. Это несколько переменных (которые называются полями), объединенных под одним именем.
Синтаксис описания типа записи таков:

type <имя типа записи> = record
<имя 1-го поля записи>:<тип 1-го поля>;
<имя 2-го поля записи>:<тип 2-го поля>;
. . .
<имя N-го поля записи>:<тип N-го поля>;
end;

Отличие от записи от массива заключается в том, что элементы (поля) записи могут быть различного типа в отличие от элементов массива.
Выгод от применения записей несколько. Во-первых, все поля записи можно объявить одним махом:

var <имя записи>:<имя типа записи>;

Во-вторых, во многих случаях можно обрабатывать записи одним оператором, а не по полям (например, можно присвоить одну запись другой).
В-третьих, записи можно передавать как аргументы функциям и процедурам (и получать в качестве результата) - тоже целиком.
В-четвертых, программа становится более "читаемой", так как ясно, что все поля записи - части одного и того же объекта. Общее количество переменных сокращается и в них труднее запутаться.

Рассмотрим некоторые из этих достоинств на примере записи Человек

(TMan).

type TRace = (White, Red, Black, Yellow); { перечислимый тип Раса }
type TSex = (Male, Female); { перечислимый тип Пол }
type TMan = record
name : string; { имя }
age : byte; { возраст }
weight : integer; { вес }

height : integer; { рост }
race : TRace; { раса }
sex : TSex; { пол }
end;


Как видите, достаточно сложная структура. Но теперь объявить три таких записи можно буквально парой слов:

var man1, man2, man3: TMan;

Если бы мы не использовали запись, каждое из 6-ти ее полей пришлось бы описывать ТРИ раза - по одному для каждого человека. Для наглядности, сравните:

var name1, name2, name3 : string; { имя }
age1, age2, age3 : byte; { возраст }
weight1, weight2, weight3 : integer; { вес }
height1, height2, height3 : integer; { рост }
race1, race2, race3: TRace; { раса }
sex1, sex2, sex3 : TSex; { пол }

Далее. Допустим, человек man2 должен иметь те же данные, что и man1.
Если мы используем записи, достаточно написать:

man2 := man1;

Если нет:

name2 := name1;
age2 := age1;
weight2 := weight1;
height2 := height1;
race2 := race1;
sex2 := sex1;

Когда следует использовать записи? Когда какое-то понятие, какой-то объект требуют для своего определения несколько различных значений. В таком случае логичнее не хранить эти значения в разрозненных, не связанных между собой переменных, а описать их под одним объединяющим их именем (как TMan). И далее их использовать когда "скопом" (если мы что-то делаем со всем объектом целиком), когда по отдельным значениям (полям).
Примерами объектов, которые удобно описывать записью, являются, помимо Человека, еще Комплексное число, Студент, Автомобиль, Аудитория, Химическое соединение, Время, Дата и множество всего остального.

Необходимо определить, какие поля объекта Вам потребуются в программе, чтобы не писать лишнего (того же Человека можно описать и 10000 полей - было бы желание).
 

II. Правила применения записей.

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

другие записи и т.п.

Когда в разделе описаний описывается переменная-запись, указывается только имя записи целиком (поля "описываются" автоматически). Пример описания переменной-записи:

var man : TMan;

Здесь описаны все 6 полей записи man.
Если в программе вы что-то делаете со всей записью целиком, достаточно указать ее имя (например, man). Если же требуется только конкретное поле записи, необходимо указать имя поля И имя записи, которой поле принадлежит (эти два имени разделяется точкой):

<имя записи>.<имя поля>

Такой способ именования нужен из-за того, что соответствующие поля записей одного типа имеют тождественные имена. Например, поле Возраст (в записях типа TMan) имеет имя age и в записи man1, и в записи man2, и в man3. И если мы напишем

age := 21;

непонятно, какое же поле должно получить такое значение - которое в записи man1, или man2, или man3 ? Чтобы уточнить, о каком именно поле идет речь, к его имени и добавляется имя записи, в котором поле содержится:

man1. age := 21;
Тут уже никаких разночтений нет.
Далее. Допустим, мы объявили массив записей:

var group: array [1..30] of TMan;

Какое имя имеет, скажем, поле race 12-й записи из этого массива? Ответ:

group[12]. race

То, что стоит до точки, является именем записи (запись из массива group с индексом 12), после точки - имя поля. Аналогично конструируются другие имена для массива записей.
Другая ситуация - когда поле записи само является записью. Например, заменим поле name в записи TMan на запись TTitle:

type TTitle = record
name : string; { имя }
patronymic : string; { отчество }
family : string; { фамилия }
end;
TMan2 = record
title : TTitle; { вместо поля name }
... { дальше те же поля, что и раньше }
end;

var man1, man2, man3 : TMan2;

Тогда какое имя будет иметь поле patronymic в поле title записи man2 ?

Ответ:

man2. title. patronymic

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

with <имя записи> [,<имя поля записи>, <имя поля записи> ...] do
begin
<операторы, в которых фигурируют имена полей записи>
end;

После with указывается <имя записи>, c полями которой Вы хотите работать. Если отдельные поля этой записи сами являются записями (как поле title в TMan), можно через запятую указать и их имена. Однако можно указать поля только записи <имя записи>, но не других записей (даже того же типа). В теле оператора with все имена, начальные части которых совпадают с записанными после with, можно писать в сокращенном виде - без этих начальных частей (т.е. просто как имена полей, без точек).

Пример:

with man2, man2. title do
begin
patronymic := 'Васильевич'; { вместо man2.title.patronymic }
age := 21; { вместо man2.age }
end;


Обратите внимание, что оператор

with man1, man2 do ...

НЕДОПУСТИМ! В нем указаны имена двух РАЗЛИЧНЫХ записей.

Наконец, последнее замечание. При работе с полями записи помните, что это в сущности обычные переменные, которые обладают всеми свойствами своего типа, и к ним применимы все операции, ограничения и правила для это типа. Другими словами, если поле записи - массив целых чисел, обращайтесь с этим полем, как с массивом из целых чисел. Ничего не меняется от того, что это не самостоятельная переменная, а поле записи (кроме имени).
 

III. Ввод и вывод записей

К сожалению, запись, как и другие сложные типы данных, невозможно ввести или вывести целиком, сразу одним оператором ввода или вывода. Запись вводится и выводится по полям - т.е. каждое поле отдельно. Но (см. последнее замечание предыдущей главы) поле записи само может быть сложного типа (массив и т.п.) и для его ввода тоже придется писать соответствующую конструкцию (вроде цикла для ввода массива).
В качестве примера разберем ввод и вывод записи man типа TMan2. Сначала ввод (переменная k имеет тип integer):

writeln('Введите запись man:');
with man, man. title do
begin
write('Имя: '); readln(name);
write('Отчество: '); readln(patronymic);
write('Фамилия: '); readln(family);
write('Возраст: '); readln(age);
write('Вес: '); readln(weight);

write('Рост: '); readln(height);
write('Раса (1-Белая 2-Красная 3-Черная 4-Желтая): ');
readln(k);
case k of
1: race = White;
2: race = Red;
3: race = Black;
4: race = Yellow;
else writeln('Ошибка! Число должно быть от 1 до 4');
end;
write('Пол (1-Мужской 2-Женский): ');

readln(k);
case k of
1: sex = Male;
2: sex = Female;
else writeln('Ошибка! Число должно быть от 1 или 2');
end;
end;

Обратите внимание, что поле title вводится тремя (а не одним) операторами, так как является записью из трех полей. Поля race и sex вводятся через числовое значение и оператор case, так как переменные перечислимого типа напрямую ввести невозможно.
Если Вам кажется, что приведенный фрагмент излишне сложен, попытайтесь написать его без применения записей.
При вводе использован оператор with для сокращения имен. Если в записи два-три простых поля, with применять, конечно, не обязательно. Например, запись Комплексное число

type Complex = record
Re: real;
Im: real;
end;

var x : Complex;

можно ввести так (без with):

writeln('Введите комплексное число x:');
write('Re = '); readln(x. Re);
write('Im = '); readln(x. Im);

Ввод больших записей (таких, как TMan2) удобно оформлять в виде процедуры с одним параметром:

procedure ReadMan( var man : TMan2);
begin
<вышеприведенный фрагмент ввода записи man>
end;

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

writeln('Данные записи man:');
with man, man. title do
begin
writeln('ФИО: ', name, ' ', patronymic, ' ', family);
writeln('Возраст: ', age);
writeln('Вес: ', weight);
writeln('Рост: ', height);
write('Раса: ');

case race of
White: writeln('Белая');
Red: writeln('Красная');
Black: writeln('Черная');
Yellow: writeln('Желтая');
end;
write('Пол: ');
case sex of
Male: writeln('Мужской');
Female: writeln('Женский');

end;
end;

А для комплексного числа вывод будет выглядеть так:
writeln('x = ', x.Re:5:2, ' + ', x.Im:5:2, 'i');
 

 

Сайт создан в системе uCoz