CFA LogoCFA Logo Computer
Новости Статьи Магазин Драйвера Контакты
Новости
RSS канал новостей
В конце марта компания ASRock анонсировала фирменную линейку графических ускорителей Phantom Gaming. ...
Компания Huawei продолжает заниматься расширением фирменной линейки смартфонов Y Series. Очередное ...
Компания Antec в своем очередном пресс-релизе анонсировала поставки фирменной серии блоков питания ...
Компания Thermalright отчиталась о готовности нового высокопроизводительного процессорного кулера ...
Компания Biostar сообщает в официальном пресс-релизе о готовности флагманской материнской платы ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2002 ГОД

Мысли о Паскале

Владислав ДЕМЬЯНИШИН nitromanit@mail.ru

(Продолжение, начало см. МК № 46, 51—52, 4, 6—7, 10, 12—13 (165, 170—171, 175, 177—178, 181, 183—184))

Комбинированные типы (записи)

Записи и селекторы

Комбинированные типы, как и регулярные типы, являют собой правило формирования составных типов. В отличие от массивов, записи позволяют объединить значения РАЗЛИЧНЫХ типов и поэтому являются, видимо, наиболее гибким механизмом построения данных.

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

• фамилия, имя и отчество (символьные массивы или строки);

• пол (перечислимый тип из двух значений);

• индекс специальности (целое), и т. д.

Для представления такой разнородной, но логически связанной информации удобно использовать комбинированный тип (запись). Необходимо отметить, что в данном случае определенные компоненты комбинированного типа, ввиду их различной природы, не могут идентифицироваться порядковыми номерами (индексами), как в массивах, поэтому для обозначения компонент используются идентификаторы (имена). Таким образом, описание комбинированного типа представляет собой список описаний его элементов (которые называются также полями записи); каждое описание похоже на описание простой переменной. Список полей начинается служебным словом record и должен завершаться служебным словом end. Для примера, приведенного выше, описание комбинированного типа TPerson (человек) может выглядеть следующим образом:

Последняя точка с запятой перед словом end может быть опущена.

Итак, структура записи состоит из фиксированного числа компонент (полей), каждое из которых имеет собственное (уникальное в пределах этой записи) имя и ПРОИЗВОЛЬНЫЙ тип.

Следует помнить, что в записи не может быть двух и более полей с одинаковыми именами.

Имея в программе вышеприведенное описание, можно определить переменные данного типа, например:

Доступ к элементам (полям) записей производится с помощью конструкции, называемой селектором записи и имеющей общий вид:

где — переменная комбинированного типа, — имя поля. Для переменных, введенных выше, допустимы следующие конструкции:

Таким образом, записи могут состоять из нескольких полей.

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

Для переменной Group доступ к полям записей, составляющих этот массив, производится следующим образом:

Рассмотрим теперь случай, когда в составе записи содержатся поля, имеющие также тип записи. Пусть для комбинированного типа TPerson необходимо хранить информацию о дате рождения человека. Эту информацию можно представить в виде трех полей в составе типа TPerson. Однако логичнее для этого определить отдельный тип, так как в этом случае он может использоваться в описании других типов и переменных:

Теперь этот тип можно использовать в записи TPerson:

Доступ к полям из элемента BirthDay производится по общим правилам, например:

Таким образом, при написании селектора необходимо помнить, что слева от символа «точка» всегда должна находится переменная типа запись (в наших примерах такими переменными являются Group[ j ], Sasha.BirthDay и т. д.), а справа — имя поля этой записи.

Для более компактной записи селекторов Pascal имеет специальный оператор присоединения (см. главу «Операторы. Оператор над записями»), позволяющий в ряде случаев опускать части селекторов.

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

Далее можно с помощью процедур определить операции над комплексными числами (сложение, умножение, деление):

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

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

Рассмотрим опять тип TPerson, содержащий информацию о человеке. Если в этом типе поле Sex (пол) имеет значение Male (мужской), то пусть необходимо предусмотреть такие поля:

• время прохождения очередных военных сборов;

• курит человек или нет;

Если же это поле имеет значение Female (женский), то хотелось бы иметь информацию… например, о цвете глаз.

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

Любой комбинированный тип, помимо фиксированного списка полей, может содержать так называемую вариантную часть, предполагающую определение нескольких вариантов структуры этого типа. Это означает, что разные переменные, хотя и относятся к одному и тому же типу, могут иметь отличающуюся структуру. Различие может касаться как числа полей, так и их типа.

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

Теперь, основываясь на вышесказанном, перепишем тип TPerson на новый лад:

Хочу обратить ваше внимание на следующие обстоятельства:

Начало вариантной части отмечается служебным словом case; после определения поля-признака выбора вариантов записывается служебное слово of. Вариантная часть завершается служебным словом end вместе с завершением всей записи. Таким образом, в описании комбинированного типа может быть ТОЛЬКО ОДНА вариантная часть, и она должна быть задана в КОНЦЕ записи.

Альтернативы вариантной части помечаются допустимыми значениями поля Sex; определение этого типа вынесено из фиксированной части и помещено в заголовке вариантной части. Поле, значения которого задают варианты, иногда называют дискриминантом записи.

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

Имена полей во всех вариантах должны быть РАЗЛИЧНЫ и отличаться от имен полей фиксированной части.

Для некоторых значений поля-дискриминанта вариант может отсутствовать. Тогда после двоеточия может стоять пустой список вида - ).

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

Хочу отметить, что любой вариант, в свою очередь, может иметь свою вариантную часть, которая также должна располагаться в конце списка полей данного варианта.

При использовании вариантных записей необходимо учитывать следующие особенности:

• Для размещения переменной комбинированного типа всегда отводится фиксированный объем памяти, причем если в записи есть варианты, то этот объем определяется по самому большому варианту. Таким образом, различные варианты одной записи как бы «накладываются» друг на друга в памяти, т. е. занимают одну и ту же область памяти.

Pascal не содержит никаких средств контроля за правильностью работы с вариантами записей. Так, логически бессмысленная последовательность присваиваний

будет выполнена, хотя поле Smoking не предусмотрено для значения Female в поле-дискриминанте Sex. Иными словами, в любое время возможен доступ ко всем полям во всех вариантах независимо от значения дискриминанта. Считается, что за соответствием текущего значения дискриминанта и доступа к полям записи должен следить программист. Это, безусловно, может привести к различного рода логическим ошибкам и потому является одним из слабых мест языка.

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

Примером может служить схема доступа к регистрам процессора Intel 80x86. Известно, что к шестнадцатиразрядным регистрам общего назначения, именуемым обычно AX, BX, CX, DX, возможен доступ и как к единым словам, и как к отдельным их байтам; в последнем случае младшие и старшие части регистров обозначаются как AL,AH для регистра AX; и BL,BH для регистра BX и т. д., причем можно произвольным образом чередовать обращение как к регистру в целом, так и к его частям.

Turbo Pascal имеет возможность непосредственного обращения к аппаратным регистрам посредством процедур специального вида (см. главу «Системно-зависимые расширения»). Для этих целей предусмотрено следующее программное представление регистров:

Здесь дискриминант представляет собой только идентификатор (дискретного) типа, который в данном случае определяет не специальное поле, а просто задает тип констант, которыми будут «пронумерованы» варианты. Учитывая, что для всех вариантов записи резервируется общая область памяти, легко видеть, что память, отведенная для поля AX, будет совмещена с памятью для полей AL,AH,и т. д.

(Продолжение следует)

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы или вычислите пример: *
captcha
Обновить





Хостинг на серверах в Украине, США и Германии. © sector.biz.ua 2006-2015 design by Vadim Popov