2.4.2.2. Иерархические (вложенные) записи. Возможно существование записей, отдельные поля которых представляют собой также записи. Для того чтобы понять, как это реализуется, попробуем добавить в описание комбинированного типа Еmрlоуее пару полей-записей. Пусть это будут поля, содержащие информацию об адресе служащего (почтовый код, город, улица, дом, квартира) и его дате рождения (число, месяц, год). В принципе соответствующие поля (пять полей и три поля с данными соответственно об адресе и дате рождения) можно добавить непосредственно в описание комбинированного типа Еmрlоуее. А что если эту информацию впоследствии потребуется использовать в качестве полей еще в каких-нибудь комбинированных типах? Поэтому лучше для адреса и даты рождения создать самостоятельные комбинированные типы в разделе описаний программы, которые затем добавить как поля в тип Еmрlоуее. Описание этих типов может выглядеть так:
tуре
Address = rесоrd
РоstСоdе:; {Почтовый код}
City, Street:string[20]; {Город, улица}
House:word; {Дом}
Араrtment:word {Квартира}
end; {address}
Date = rесоrd
Dау:1..31; {Число}
Моnth:1..12; {Месяц}
Yеаr;1900..2000 {Год}
end; {date}
NеwЕmрlоуее = record
ID:word; {Идентификатор (личный номер)}
FirstName, SecondName, SurName : string[20];
{Имя, фамилия, отчество}
Standing: bytе; {Стаж}
Salary:rеаl {Зарплата}
BirthDate:date; {Дата рождения}
Habitation:address {Место жительства}
end;
vаr
NewAssistant: NеwЕmрlоуее;
Описанный выше комбинированный тип NеwЕmрlоуее включает восемь полей, два из которых – BirthDate (Дата рождения) и Habitation (Место жительства) – представляют собой записи, типы которых (Date и Address соответственно) объявлены перед описанием типа NеwЕmрlоуее. Структура комбинированного типа NеwЕmрlоуее представлена на рис.1.

Рис.1. Тип NewEmployee
Составные имена, с помощью которых можно обращаться к полям вложенных записей, должны включать имя основной записи, имя вложенной записи и имя поля. Например:
NеwЕmрlоуее. Аddress.РоstСоdе
или
NеwЕmрlоуее.Date.Dау
Если имеют место несколько уровней вложения записей, составные имена могут быть очень длинными. Однако ничто не мешает в этих случаях широко применять оператор WIТН.
2.4.2.3. Записи с вариантами. Иногда возникает необходимость, чтобы в зависимости от значения определенного поля записи структура этой записи частично изменялась. Например, одно из полей комбинированного типа Еmрlоуее, которое представляет собой вложенную запись, содержит информацию о месте жительства служащего. Однако городской адрес обычно выглядит не так, как загородный. Что если кто-либо из членов коллектива проживает за пределами города? Для решения этой проблемы Turbo Раsсаl позволяет в структуре комбинированного типа Аddress создать вариантную часть, в которой набор полей мог бы изменяться в соответствии с видом адреса. Итак, в структуре адреса необходима некоторая фиксированная часть – группа полей, присутствующих постоянно, независимо от характера адреса, и вариантная часть с изменяющимся набором полей. Фиксированная часть в нашем случае могла бы включать поля PostCode (почтовый код), Street (улица) и Ноusе (дом) – элементы, присутствующие в любом адресе. Вариантная часть записи для городского адреса могла бы включать поля City и Apartment (город и квартира), а для загородного адреса – поля Аrеа (область), District (район) и Community (населенный пункт). Для управления вариантной частью адреса введем в структуру комбинированного типа Address поле City_оr_Country (город/загород), для которого допустимы только значения City и Country. Вот как может выглядеть описание такого преобразованного комбинированного типа (присвоим ему имя NewAddress):
tуре
NewAddress = rесоrd
РоstСоdе:; {Почтовый код}
Street:string[20]; {Город, улица}
House:word; {Дом}
саsе City_оr_Country : City, Country оf
City:(City:string[20]; {Город}
Appartment:word); {Квартира}
Соuntrу :(Аrеа,District, {Область, район}
Community:string[20]); {Населенный пункт}
end; {NewAdress}
Фиксированная часть записи всегда предшествует вариантной части. Описание фиксированной части ничем не отличается от описания обычной записи (без вариантов). Вариантная часть начинается со строки,
саsе City_оr_Countrу : City, Countrу оf
которая объявляет специальное поле City_оr_Countrу, способное принимать только два значения (Citу и Сountrу – т. е. принадлежит перечислимому типу). Это поле, которое называется полем признака (или селектором выбора – по аналогии с оператором САSЕ), определяет вариантную часть записи.
Строка, начинающая вариантную часть, включает зарезервированные слова CASE и OF, имеющие смысл вариант и из соответственно Дальше следует перечень меток, представляющих собой все допустимы значения поля признака (в нашем случае две метки – City и Country). После каждой метки (за двоеточием, в круглых скобках) представлен перечень полей для данного варианта, причем для каждого поля указывается тип. Завершение данной конструкции CASE-OF – перечень меток ключевым словом ЕND не предусмотрено. Правда, в конце описание комбинированного типа NewAddress слово ЕND все же имеется, однако оно здесь служит парой зарезервированному слову RECORD, а не CASE. Иначе говоря, то, что мы здесь видим, вовсе не представляет собой оператор CASE, а является всего лишь конструкцией, внешне похожей на оператор САSЕ, описывающей вариантную часть записи.
Структура комбинированного типа NewAddress представлена на рис.2.
При использовании записей с вариантами следует иметь в виду следующие особенности.
• В записи может быть только одна вариантная часть, которая должна быть описана непременно после фиксированной части.
• Поле признака вариантной части не принадлежит ни к фиксированной, ни к вариантной частям и выносится в заголовок вариантной части.
• Идентификаторы всех полей записи – как в фиксированной, так и в вариантной части – должны быть уникальными (не совпадать).
• Для некоторых меток допускается "пустой вариант". В этом случае после двоеточия следует пара круглых скобок, без перечня полей.
• Объем памяти, выделяемый для записи, определяется суммой длин полей. Объем памяти для записи с вариантами определяется по самому объемному варианту.

Рис.2. Тип NewAddress
В созданном нами комбинированном типе NеwЕmрlоуее мирно сосуществуют вложенные записи (Date и NewAddress) и записи с вариантами. Собственно, вложенная запись NewAddress одновременно является записью с вариантами. Этот пример наглядно иллюстрирует, насколько сложные структуры данных можно создавать с использованием записей.
И это еще не все, что касается сложности структур, которые позволяют создавать комбинированные типы.
2.4.2.4. Применимые операции. В этом разделе суммируются сведения о действиях, позволяющих манипулировать записями. Причем выделяются две категории действий: применимые к полям записей и к записям в целом.
Действия над полями записи
Поскольку поле записи трактуется как переменная, оно может фигурировать в выражениях. (Как обратиться к полю записи, мы выяснили выше – для этого достаточно указать имя записи и имя поля.) Набор операций над полями записи соответствует операциям, допустимым для типа, которому принадлежит данное поле. Какие операции и подпрограммы применимы к тому или иному простому типу, мы уже знаем.
Действия над записями
Здесь, вероятно, уместно повторно упомянуть оператор WITH, который так и называется: оператор над записями.
Кроме того, как и с массивами, значения переменных, принадлежащих комбинированному типу, можно присваивать другим переменным того же типа. Например, если переменные Х и Y представляют собой записи, принадлежащие одному комбинированному типу, то допустим оператор присваивания
х:=у;
В результате значения всех полей записи Х окажутся присвоены полям записи Y.
Однако нельзя использовать с записями операции сравнения. Неверно, например, было бы к записям Х и Y применить оператор
while х=у do...
Тем не менее, если такая необходимость существует, можно сравнить по очереди каждое поле одной записи с полями другой.
Совершенно не применимы к записям (в целом) арифметические и логические операции.
Кроме того, следует особо подчеркнуть, что к записям (подобно массивам, но в отличие от строк) нельзя применять стандартные процедуры Read и Write. Однако можно организовать считывание или вывод на экран каждого поля записи в отдельности.
2.4.3. Множества. Подобно массиву, множество – это совокупность связанных данных, состоящая из элементов одного типа, который называется базовым. Однако, в отличие от массива (в котором число элементов фиксировано), множество может включать произвольное число элементов.
Описание множественного типа:
Tуре
s=set of а
Здесь SЕТ и OF – зарезервированные слова, имеющие смысл множество и из; S – имя объявляемого множественного типа; А – базовый тип множества.
Вот примеры описаний множественных типов и переменных, принадлежащих этим типам:
tуре
а1=set of 1..3;
а2=set of а..е;
а3=set of char;
vаr
х:а1; у:а2; z:а3;
В качестве базового для множественного типа А1 задан интервальный тип (1..3). Переменная X, принадлежащая множественному типу А1, может принимать значения [], [I], [2], [1,2], [3], [1,3], [2,3], [1,2,3] (всего 8 (2³) значений). Иными словами, значениями множества могут быть все входящие в него подмножества – от нуля элементов (пустое множество) до всех возможных значений базового типа. Кстати, в Тurbo Pascal допускается использование (например, в операторах присваивания) явно заданных значений множественного типа, подобно, например, целочисленным или вещественным значениям. В этом случае элементы множества задаются через запятую и все значение заключается в квадратные скобки. Например:
х:=[1,3];
х:=[];
Во втором случае переменной Х присваивается так называемое пустое множество, т. е. множество, не содержащее ни одного элемента.
В качестве базового для множественного типа А2 задан диапазон а..е. Переменная Y, принадлежащая множественному типу А2, может принимать значения, соответствующие всем подмножествам, входящим в это множество (всегозначения).
Наконец, в качестве базового для множественного типа А3 выбран стандартный тип Char. Число значений, которые может принимать переменная Z (объявленная как принадлежащая типу А3), равно 2256, причем значения эти представляют собой произвольные наборы символов из таблицы ASCII. Например, переменная Z может иметь значение
[‘3’, ‘f’, ‘(‘, ‘#’, ‘п’, ‘Л’]
Значение переменной Z можно представить и так:
[сhr(45),сhr(54),сhr(58),сhr(65),сhr(73),сhr(78),сhr(89)].
Помимо того, что множество может включать произвольное число элементов, имеет место еще одно отличие множеств от массивов. Если массив – это упорядоченная совокупность элементов, то в множестве порядок элементов никак не фиксируется. Так. [1,2,3,4,5] и [5,2,1,4,3] – это одно множество. Кроме того, все элементы в множестве должны быть различными. Иными словами, [1,2,3] и [1,1,2,3,3,3] – это также одно множество.
Представление множества возможно путем перечисления входящих в него элементов или заданием диапазона (если члены множества образуют неразрывную последовательность), т. е. множество [1,2,3,4,5] можно также представить как [1..5]. Допускается сочетание двух методов: [1..5,7,9].
Число элементов множества в Turbo Pascal не должно превышать 256 (причем, для целочисленных типов эти значения должны лежать в диапазоне (0,...,255). Вследствие этого ограничения в качестве базовых типов для множеств (из стандартных типов) могут служить только Byte, Char и Boolean. Не удастся использовать для множества в качестве базового, например, тип Integer, хотя подходят интервальные типы, образованные на основе integer.
2.4.3.1. Применимые действия. Набор допустимых для множеств операций включает проверку принадлежности элемента множеству; объединение, пересечение и вычитание множеств; сравнение множеств (проверку равенства и неравенств множеств, а также проверку принадлежности одного множества другому).
Проверка принадлежности элемента множеству
Для этой операции в Turbo Pascal имеется специальный оператор IN. Выражение с этим оператором возвращает значение типа Boolean. Вот пример использования оператора IN:
а in [1,3,5,7,9]
Это выражение проверяет, принадлежит ли значение переменной A данному множеству и возвращает значение TRUE либо FALSE. В случае, если бы оператора IN не существовало, нам пришлось бы воспользоваться гораздо более громоздким выражением для проверки данного условия:
(а=1) оr (а=3) оr (а=5) оr (а=7) оr (а=9)
В случае, если переменная А принадлежит множеству [1,3,5,7,9] оба выражения возвратят значение TRUE. Еще примеры:
3 in [1,3,5,7,9];
4 in [1,3,5,7,9];
Эти выражения возвратят значения TRUE и FALSE соответственно.
Объединение, пересечение и вычитание множеств
Эти операции, будучи применены к двум множествам, формируют третье. В Turbo Pascal эти операции обозначаются символами: + (объединение), * (пересечение), - (вычитание).
В результате объединения двух множеств А и В формируется третье, содержащее все элементы, встречающиеся в первых двух множествах (см. рис.3). Примеры можно видеть в табл.8.
Таблица 8
Примеры объединения двух множеств
Объединение множеств | Результат |
[1,2,3,4,5]+[3,4,5,6,7] | [1,2,3,4,5,6,7] |
[1,2]+[3,4] | [1,2,3,4] |
[‘a’,’b’,’c’]+[‘A’,’B’,’C’] | [‘a’,’b’,’c’,’A’,’B’,’C’] |
[‘1’,’3’,’5’,’7’,’9’]+[‘1’,’3’,’5’,’A’,’B’] | [‘1’,’3’,’5’,’7’,’9’,’A’,’B’] |
Часто возникает необходимость добавить в множество новый элемент (частный случай операции объединения). Эта задача может быть решена следующим образом:
[1,2,3,4,5]+[6]
В результате пересечения двух множеств А и В формируется третье множество, содержащее только элементы, одновременно принадлежащие первым двум множествам (см. рис.3). Примеры можно видеть в Табл.9.
Таблица 9
Примеры пересечения двух множеств
Пересечение множеств | Результат |
[1,2,3,4,5]*[3,4,5,6,7] | [3,4,5] |
[1,2]*[3,4] | [] |
[‘a’,’b’,’c’]*[‘A’,’B’,’C’] | [] |
[‘1’,’3’,’5’,’7’,’9’]*[‘1’,’3’,’5’,’A’,’B’] | [‘1’,’3’,’5’] |
При вычитании множества В из множества А формируется третье множество, содержащее только элементы, принадлежащие множеству А и не принадлежащие множеству В (см. рис.3). Примеры можно видеть Табл.10.
Таблица 10
Примеры вычитания двух множеств
Вычитание множеств | Результат |
[1,2,3,4,5]-[3,4,5,6,7] | [1,2] |
[1,2]-[3,4] | [1,2] |
[‘a’,’b’,’c’]-[‘A’,’B’,’C’] | [‘a’,’b’,’c’] |
[‘1’,’3’,’5’,’7’,’9’]-[‘1’,’3’,’5’,’A’,’B’] | [’7’,’9’] |
Необходимо иметь в виду, если в случае объединения и пересечения множества А и В поменять местами, результат не изменится, но, однако это вовсе не так для вычитания множеств. Пример можно видеть в табл.11.
Таблица 11
Перестановка множеств при вычитании
Вычитание множеств | Результат |
[‘1’,’3’,’5’,’7’,’9’]-[‘1’,’3’,’5’,’A’,’B’] | [’7’,’9’] |
[‘1’,’3’,’5’,’A’,’B’]-[‘1’,’3’,’5’,’7’,’9’] | [‘A’,’B’] |
Операции объединения, пересечения и вычитания множеств А и B можно представить графически, если изобразить эти множества в виде некоторых фигур (например, кругов), закрашенные части которых соответствуют множествам-результатам (рис.3).

Рис. 3. Объединение, пересечение и вычитание множеств
Сравнение множеств
К операциям сравнения множеств относятся проверка равенства неравенства множеств, а также проверка принадлежности одного множества другому. Символы, которыми в Turbo Pascal обозначаются эти операции, представлены в табл.12.
Таблица 12
Операции сравнения множеств
Обозначение | Действие |
= | Проверка равенства множеств |
<> | Проверка неравенства множеств |
<= | Проверка вхождения множества слева в множество справа |
| Проверка вхождения множества справа в множество слева |
Результат сравнения представляет собой значение типа Boolean (TRUE или FALSE – в зависимости от успеха проверки). Два сравниваемых множества должны иметь один базовый тип.
Операции = и <> проверяют, совпадает ли набор элементов в сравниваемых множествах. Примеры этих операций можно видеть в табл.13 и 14.
Таблица 13
Проверка равенства множеств
Сравниваемые множества | Результат |
[1,2,3]=[1,2,4] | FALSE |
[1,2,3]=[1,2,3] | TRUE |
[1,2,3]=[3,2,1] | TRUE |
[1,2]=[1,1,2,2,3] | FALSE |
Таблица 14
Проверка неравенства множеств
Сравниваемые множества | Результат |
[1,2,3]<>[1,2,4] | TRUE |
[1,2,3]<>[1,2,3] | FALSE |
[1,2,3]<>[3,2,1] | FALSE |
[1,2]<>[1,1,2,2,3] | TRUE |
Операции <= и >= проверяют, входит ли одно множество в другое. Множество слева входит в множество справа, если все элементы левого множества встречаются среди элементов правого множества. Примеры проверок по вхождению одного множества в другое представлены втабл.15 и 16.
Таблица 15
Проверка вхождения левого множества в правое
Сравниваемые множества | Результат |
[1,2,3]<=[1,2] | FALSE |
[1,2,3]<=[1,2,3,4,5] | TRUE |
[1,2,3]<=[4,3,2,1] | TRUE |
[1,2,3]<=[1,3] | FALSE |
Множество справа входит в множество слева, если все элементы правого множества встречаются среди элементов левого множества.
Таблица 16
Проверка вхождения правого множества в левое
Сравниваемые множества | Результат |
[1,2,3]>=[1,2] | TRUE |
[1,2,3]>=[1,2,3,4,5] | FALSE |
[1,2,3]>=[4,3,2,1] | FALSE |
[1,2,3]>=[1,3] | TRUE |
2.5. Совместимость типов
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 |


>=