TYPE A=RECORD
<Имя свойства>: B;
<Имя свойства>: C
END
Таким образом, запись - это агрегат, составленный из разнородных свойств. Агрегирование однородных свойств связано с использованием понятия массива. Например, декларация
TYPE A = ARRAY [1:3] OF B
определяет агрегат А con-of(B,B,B). Размер элемента хранения объекта-агрегата определяется простым суммированием размеров элементов хранения его компонент, для последнего примера:
TSIZE (A) = 6 / TSIZE(B)=2.
Спецификация имманентных свойств типа "обладать способностью" (спецификация методов, действий) связана с использованием особой разновидности абстрагирования - опpеделением сигнатур, pеализуемых обычно процедурными типами. Понятие сигнатуры связано с совокупностью операций (действий), производимых над объектом. Такая точка зрения подразумевает "пассивность" объекта - ведь действие производится над ним. Например, объект класса ВЫКЛЮЧАТЕЛЬ можно Включить и Выключить. Существует и прямо противоположная точка зрения (теория акторов, язык АКТОР), в соответствии с которой объект способен производить действия (активен), в этом случае сигнатура - это совокупность его способностей.
Для опpеделения сигнатур используются процедурные типы. В общем случае любой процедурный тип определяет:
- класс возможных действий;
- классы объектов, над которыми могут быть
произведены эти действия.
Например, спецификация
TYPE DST = PROCEDURE (VAR ВЫКЛЮЧАТЕЛЬ)
определяет возможные действия над объектами класса ВЫКЛЮЧАТЕЛЬ. Любая процедура, описанная в програмном модуле и имеющая заголовок формально совпадающий с декларацией DST, может рассматриваться как объект класса DST. Например, действия "включить" и "выключить" могут рассматриваться как элементы класса DST только при условии, что заголовки процедур, описывающих эти действия, определены в следующем виде :
PROCEDURE Включить (VAR S: ВЫКЛЮЧАТЕЛЬ);
PROCEDURE Выключить (VAR S: ВЫКЛЮЧАТЕЛЬ);.
Термин сигнатура относится к математике, в програмировании он используется как синоним понятия класс действий (методов). В Модуле-2 существует конкретный процедурный тип, объектами которого являются процедуры без параметров:
ТYPE PROC = PROCEDURE (); .
Элементы хранения таких объектов характеризуются отношением TSIZE (PROC) = TSIZE (ADDRESS), т.е. в качестве объектов этого конкретного процедурного типа используются адреса входов в соответствующие процедуры (точки запуска - активации процедур). Это отношение спpаведливо для любого пpоцедуpного типа. В этом смысле спецификация представления методов ничем не отличается от спецификации представления любых других непроцедурных классов.
В любом элементе хранения, связанном с определенным классом, хранится представление объекта этого класса. Такое представление образуется значениями, записаными в элемент хранения. Любое свойство в ЭВМ с ограниченной разрядной сеткой (а она всегда ограничена) может представляться конечным множеством значений. Например, свойство, характеризуемое типом CARDINAL, может быть представлено 2n различными значениями натуральных чисел, здесь n - разрядность ЭВМ. Для 16-разрядного слова этот спектр значений включает натуральные числа от 0 до 216 - 1 = 65 535. Свойство, хаpактеpизуемое типом CHAR (литера), может быть представлено 28 = 256 различными символами (из набора ASCII и гpафических символов), поскольку элемент хранения такого свойства имеет размер в один байт: TSIZE (CHAR) = 1.
Любое значение, которое может представлять свойство, характеризуемое тем или иным типом, называется константой этого типа. Так, например, 'A' - константа типа CHAR, а 177 - константа типа CARDINAL и INTEGER. Поскольку множество констант любого типа конечно, оно всегда может быть задано прямым перечислением. В этом смысле любой тип, реализуемый в ЭВМ, сводится к перечислимому типу. Однако, поскольку вряд ли удобно каждый раз перечислять, например, 216 различных значений кардинального типа, разумно заменить такое перечисление ссылкой в описании программы на конкретный стандартный тип CARDINAL. Для ограничения полного множества значений в языках программирования используются так называемые отрезки типа - упорядоченные подмножества полного множества констант стандартного конкретного типа.
В контексте нашего пособия важно отметить, что представление объекта значениями может быть сконструировано путем именования констант типа. Для реализации этой возможности используется перечисление, например:
TYPE Нота=(До, Ре, Ми, Фа, Соль, Ля, Си); .
Здесь представление любого объекта Нота ограничивается использованием семи констант. Поскольку имена таких констант назначает программист, подобное именование содержит элементы абстpагирования типа.
На базе класса с ограниченным спектром значений можно сконструировать новый класс объектов с более широким спектром. Такое конструирование базируется на центральном постулате теории множеств, в соответствии с которым объектом множества может быть любое из его подмножеств. Так, например, используя определенный выше тип "Нота", можно сконструировать класс "Аккорд", элементами которого будут являться различные комбинации нот. Для этого в языках программирования используется множественный тип, определяемый на основе базового перечислимого типа:
TYPE Аккорд = SET OF Нота; .
Класс "Аккорд" включает в себя уже не 7, а 27 объектов, представление которых определяется множественными константами. Среди них:
{ До } -"чистая" нота "До";
{ До, Ми } -аккорд, составленный из двух нот;
{ До..Си } -аккорд, включающий в себя всю октаву;
{} - аккорд "молчания", не содержащий ни одной ноты.
Элемент хранения объекта "Аккорд" должен допускать размещение в нем 27 различных значений, следовательно, минимальным адресуемым элементом, пригодным для хранения аккордов, является байт:
TSIZE(Аккорд) =1.
Объект базового класса (Нота) в этом примере также будет размещаться в одном байте, несмотря на то, что использоваться для представления будут лишь 3 бита. Множественный тип, построенный на основе отрезка типа [0..15], образует стандартный тип
BITSET = SET OF [0..15].
Нетрудно заметить, что TSIZE(BITSET)=2 (байта). Размер элемента хранения любого множественного типа в байтах определяется выражением
N DIV 8 +(N MOD 8) DIV (N MOD 8).
Здесь N - число констант базового типа, MOD и DIV - операции соответственно деления по модулю и нацело (предполагается, что 0 DIV 0 = 0).
Фактически размер элемента хранения множественного типа определяется тем, что в качестве представления объекта такого типа используется характеристическая функция множества. Например, представление аккоpда {До,Ми,Си} в байте будет выглядеть следующим образом:
Си Ля Соль Фа Ми Pе До
┌──┬──┬──┬────┬──┬──┬──┬──┐ (7-й бит не
│ ?│ 1│ 0│ 0│ 0│ 1│ 0│ 1│ используется)
└──┴──┴──┴────┴──┴──┴──┴──┘
7 6 5 4 3 2 1 0
Над объектами множественного типа определены функции, связанные с элементарными операциями над множествами (объединение, пересечение, разность, симметрическая разность); проверкой состояния множества (по характеристической функции); включением/исключением базовых объектов в множество и т.п. Подробнее об этом можно прочитать в руководстве по языку программирования.
Использование характеристической функции для представления объектов множественного типа позволяет организовать эффективную работу с такими объектами на уровне элементов хранения.
III. ИДЕНТИФИКАЦИЯ ОБЪЕКТОВ
Идентификация именованием.- Квалидент.- Дистанция доступа.- Опеpатоp пpисоединения.- Индексиpование.- Идентификация указанием.- Свободный и огpаниченный указатели.- Тип ADDRESS.- Квалидент с постфиксом "^".
Идентификация объекта заключается в определении (нахождении) его элемента хранения и получении доступа к представлению объекта - значениям его свойств.
Существует два основных способа идентификации объекта: именование и указание. Именование заключается в назначении объекту определенного имени. Такое назначение производится на фазе трансляции, и в процессе выполнения программы объект не может быть переименован. Например, декларация
VAR A,B: Объект
определяет наличие в программе двух объектов с именами А и B соответственно, каждый из которых имеет индивидуальный элемент хранения. Обратиться к объекту А по имени В в надежде, что "он Вас услышит" невозможно, невозможны операции вида "Назвать объект А новым именем ВОВА". Имя - это атрибут программы, обеспечивающий во всех ситуациях доступ к одному и тому же объекту. Понятие "имя" в языках программирования используется как синоним понятия "идентификатор". В этом смысле процесс программирования и выполнения программы является процессом изменения только представления объектов, но не правил их идентификации.
Именоваться могут и отдельные свойства объектов-агрегатов. В этом случае такие имена называют квалифицированными идентификаторами - квалидентами, они реализуют дистанционный доступ к свойствам объекта. Например,
TYPE Объект = RECORD
B : Дата_рождения; П : Bес
END;
VAR A,B : Oбъект; .
Квалидент A.B откроет доступ к дате рождения объекта A, B.B - к дате рождения объекта B и т.д. Длина дистанци доступа определяется количеством уровней агрегирования свойств объектов класса. В этом примере Длина=1. Если уточнить свойство Дата_Рождения: