Примечание. Относящиеся к выражениям универсального типа правила изложены в разд. 4.10. Из этих правил следует, что именованное число имеет универсальный_ целый тип, если каждое содержащееся в выражении первичное имеет этот тип. Аналогично, если каждое первичное имеет тип универсальный-вещественный, то именованное число имеет этот тип.
Примеры описаний чисел:
ПИ : constant: = 3.14159_26536; --вещественное
- - число
ДВА_ПИ : constant : = 2.0*ПИ; - - вещественное число
МАКСИМУМ : constant : = 500; -- целое число
СТЕПЕНЬ_16: constant : = 2 * * 16; -- целое 65_536
ОДИН, ONE, EINS: constant : = 1; - - три различных имени 1
Типы и подтипы
Тип характеризуется набором значений и набором операций (точнее: операций типа или операций над типом).
Существует несколько классов типов. Скалярные типы — это целые и вещественные типы и типы, определенные перечислением своих значений; значения этих типов не имеют компонентов. Индексируемый и именуемый типы являются составными. Значение составного типа состоит из значений компонентов. Ссылочный тип — это тип, значения которого обеспечивают доступ к объектам. Личные типы - это типы, для которых полностью определяется набор возможных значений, но непосредственный доступ к ним пользователей невозможен. Наконец, существуют задачные типы. (Личные типы описаны в гл. 7, задачные — в гл. 9, остальные - в гл. 3).
Именуемые и личные типы могут иметь специальные компоненты, называемые дискриминантами, значения которых различают альтернативные формы значений каждого из этих типов. Если личный тип имеет дискриминанты, они известны пользователям типа. Следовательно, личный тип известен только своим именем, своими дискриминантами, если они есть, и соответствующим набором операций.
Набор возможных значений данного типа может зависеть от условия, которое называется ограничением (сюда же относятся случаи без ограничения) ; значение удовлетворяет ограничению, если оно удовлетворяет соответствующему условию. Подтип — это тип вместе с ограничением; говорят, что значение принадлежит подтипу, если оно принадлежит типу и удовлетворяет ограничению; данный тип называется базовым типом подтипа. Тип является подтипом самого себя; такой подтип называется неограниченным; он соответствует условию, которое не налагает никаких ограничений. Базовым типом типа является он сам.
Набор операций, определенных над конкретным типом, определен и для любого его подтипа; однако переменной данного подтипа можно присвоить значение только этого подтипа. Дополнительные операции, например, квалификация (в квалифицированном выражении), неявно определяются описанием подтипа.
Для объектов некоторых типов определено начальное значение по умолчанию; некоторые другие типы имеют выражения по умолчанию, определенные для части или всех своих компонентов. Некоторые операции над типами и подтипами называются атрибутами; эти операции обозначаются формой имени, описанной в разд. 4.1.4.
Термин подкомпонент используется в описании языка вместо термина компонент, чтобы указать компонент другого компонента или подкомпонента. Если нет других подкомпонентов, используется термин компонент.
Данный тип не должен иметь подкомпонентов, типом которых является он сам.
Имя класса типов используется в описании языка для квалификации объектов и значений, принадлежащих к типу рассматриваемого класса. Например, термин „индексируемый объект” используется для объекта индексируемого типа; аналогично термин „ссылочное значение” используется для значения ссылочного типа.
Примечание. Набор значений подтипа - это подмножество значений базового типа. Это подмножество не обязано быть собственным подмножеством; оно может быть пустым.
О п и с а н и я типов
Описание типа объявляет тип.
описание—типа : : = полное—описание_типа
І неполное_описание_типа I описание _личного_типа полное_описание_типа : : =
type идентификатор [раздел_дискриминантов]
is определение_типа;
определение_типа : : = определение_перечислимого_типа
I определение—целого—типа
I определение—вещественного—типа
I определение—индексируемого_типа
I определение—именуемого—типа
I определение—ссылочного—типа
I определение—производного—типа
Предвыполнение полного описания типа состоит из предвыполнения раздела дискриминантов, если он есть (исключая случай, когда дается полное описание типа для уже встречавшегося неполного описания типа или для описания личного типа), и предвыполнения определения типа.
Типы, созданные в результате предвыполнения различных определений, являются различными. Более того, предвыполнение определения типа для числовых или производных типов создает как базовый тип, так и подтип базового типа; то же самое следует сказать об определении ограниченного индексируемого типа (одной из двух форм определения индексируемого типа).
Простое имя в полном описании типа обозначает описанный тип, если только описание типа не объявляет одновременно базовый тип и подтип базового типа; в этом случае простое имя обозначает подтип, а базовый тип является анонимным. Тип называется анонимным, если он не имеет простого имени. Для наглядности в этом стандарте время от времени используется псевдоимя анонимного типа, выделенное курсивом там, где обычно по синтаксису требуется идентификатор.
Примеры определений типов:
(БЕЛЫЙ, КРАСНЫЙ, ЖЕЛТЫЙ, ЗЕЛЕНЫЙ, ГОЛУБОЙ, КОРИЧНЕВЫЙ, ЧЕРНЫЙ) range 1 . . 72
array (1 . . 10) of INTEGER
Примеры описаний типов:
type ЦВЕТ is (БЕЛЫЙ, КРАСНЫЙ, ЖЕЛТЫЙ, ЗЕЛЕНЫЙ, ГОЛУБОЙ, КОРИЧНЕВЫЙ, ЧЕРНЫЙ) ;
type СТОЛБЕЦ is range 1 . . 72;
type ТАБЛИЦА is array (1 . . 10) of INTEGER;
Примечание. Два определения типа всегда определяют два различных типа, даже если они текстуально идентичны. Таким образом, данные ниже описания А и В задают различные индексируемые типы:
array (1 . . 10) of BOOLEAN;
array (1 . . 10) of BOOLEAN;
Если А и В описаны в групповом описании объектов
А,В: array (1 . . 10) of BOOLEAN;
то их типы (анонимные) тем не менее различны, так как это групповое описание объектов эквивалентно двум приведенным выше единичным описаниям.
Неполные описания типов используются для определения рекурсивных и взаимосвязанных типов (см. 3.8.1). Описания личных типов используются в спецификациях пакетов и в описаниях параметров настройки (см. 7.4 и 12.1).
О п и с а н и е подтипов
Описание подтипа объявляет подтип.
описание_подтипа : : =
subtype идентификатор is указание_подтипа;
указание—подтипа : : — обозначение—типа [ограничение] обозначение_типа : : = имя_типа | имя_подтипа
ограничение : : = ограничение—Диапазона
I ограничение—плавающего—типа
I ограничение—фиксированного—типа
I ограничение—индекса
I ограничение—дискриминанта
Обозначение типа обозначает тип или подтип. Если обозначение типа — имя типа, то оно обозначает этот тип, а также соответствующий неограниченный подтип. Базовым типом, соответствующим обозначению типа, является, по определению, базовый тип типа или подтипа, указанного обозначением типа.
Указание подтипа определяет подтип базового типа, соответствующего обозначению типа.
Если в указании подтипа после обозначения типа стоит ограничение индекса, то обозначение типа не должно обозначать подтип с уже ограниченным индексом. Аналогично, для ограничения дискриминанта обозначение типа не должно иметь ограничение дискриминанта.
Предвыполнение описания подтипа состоит из предвыполнения указания подтипа. Это предвыполнение создает подтип. Если указание подтипа не включает ограничение, то определяемый подтип тот же, что и указанный обозначением типа. Предвыполнение указания подтипа, содержащего ограничение, происходит следующим образом:
вначале предвыполняется ограничение;
Ограничение проверяется на совместимость с типом или подтипом, заданным обозначением типа.
После предвыполнения ограничения получается условие, наложенное ограничением. (Правила предвыполнения ограничения таковы, что выражения и диапазоны ограничений вычисляются при предвыполнении всех этих ограничений.) Правила определения совместимости даны в соответствующих разделах для каждой формы ограничения. Эти правила таковы, что если ограничение совместимо с подтипом, то наложенное ограничением условие не может противоречить никакому условию, уже заданному для значений этого подтипа. В противном случае возбуждается исключение CONSTRAINT-ERROR.
Примеры описаний подтипов: '
subtype РАДУГА is ЦВЕТ range КРАСНЫЙ . . ГОЛУБОЙ; - - см. 3.3.1
subtype КРАСНЫЙ_голубой is РАДУГА;
subtype ЦЕЛ is INTEGER;
subtype МАЛОЕ_ЦЕЛ is INTEGER range - - 10 .. 10;
subtype ВПЛОТЬ_ДО_К is СТОЛБЕЦ range 1 .. K; - - cm. 3.3.1
subtype КВАДРАТ is МАТРИЦА (1 .. 10,1 . . 10) ; - - см. 3.6
subtype МУЖЧИНА is ПЕРСОНА (ПОЛ = > M) ; - - см. 3.8
Примечание. Описание подтипа не определяет нового типа.
К л а с с и ф и к а ц и я операций
Набор операций над типом включает явно описанные подпрограммы с параметром или результатом этого типа; такие подпрограммы необходимо описывать после описания типа.
Остальные операции неявно описываются сразу после каждого описания соответствующего типа. К ним относятся базовые операции, предопределенные операции (см. 4.5) и литералы перечисления. Описанием производного типа неявно задаются операции, включающие производные подпрограммы. Считается, что неявные описания операций расположены между описанием типа и последующим описанием, если таковое имеется. Неявные описания производных подпрограмм расположены последними.
Базовыми операциями являются:
Присваивание (в операторах присваивания и инициализациях), генератор, проверка принадлежности и форма управления с промежуточной проверкой;
Именуемый компонент, индексируемый компонент и отрезок;
Квалификация (в квалифицированных выражениях), явное преобразование типа, и неявное преобразование значения типа универсальный _це- лый или универсальный_вещественный в соответствующее значение другого числового типа;
Числовой литерал (для универсального типа), литерал null (для ссылочного типа), строковый литерал, агрегат или атрибут.
Для каждого типа или подтипа Т определен следующий атрибут: T'BASE. Базовый тип Т. Этот атрибут допустим только в качестве префикса имени другого атрибута, например, T'BASE'FIKST.
Примечание. Каждый литерал - это операция, в результате выполнения которой вырабатывается соответствующее значение (см. 4.2). Подобно этому, агрегат - это операция, в результате выполнения которой вырабатывается значение составного типа (см. 4.3). Некоторые операции оперируют со значениями данного типа, например, предопределенные операции и некоторые подпрограммы и атрибуты. Некоторые операции возвращают значение данного типа, например, литералы и некоторые функции, атрибуты и предопределенные операции. Присваивание - это операция, которая оперирует с объектом и значением. В результате выполнения операции, соответствующей именуемому компоненту, индексируемому компоненту или отрезку, вырабатывается объект или значение, обозначенное этой формой имени.
Производные типы
Определение производного типа задает новый (базовый) тип, который наследует свойства родительского типа; новый тип называется производным типом. Определение производного типа создает одновременно производный подтип, являющийся подтипом производного типа.
определение—производного_типа : : =
new указание_подтипа
Указание подтипа после зарезервированного слова new определяет родительский подтип. Родительский тип является базовым для родительского подтипа. Если для родительского подтипа существует ограничение, то подобное ограничение существует и для производного подтипа; разница состоит только в том, что для ограничения диапазона и для ограничения плавающего или фиксированного типов, которое включает ограничение диапазона, значение каждой границы заменяется на соответствующее значение производного типа. Производный тип обладает следующими свойствами:
• Производный тип относится к тому же самому классу типов, что и родительский тип. Набор возможных значений для производного типа есть копия набора возможных значений для родительского типа. Если родительский тип составной, такие же компоненты существуют и у производного типа, а подтип соответствующих компонентов тот же самый;
Для каждой базовой операции над родительским типом существует соответствующая базовая операция над производным типом. Допускается явное преобразование значения родительского типа в соответствующее значение производного типа и наоборот, как поясняется в разд. 4.6;
Для каждого литерала перечисления или для каждой предопределенной операции над родительским типом существует соответствующая операция над производным типом;
Если родительский тип — заданный тип, to для каждого входа родительского типа существует соответствующий вход производного типа;
Если выражение по умолчанию существует для компонентов объекта, имеющего родительский тип, то то же самое выражение используется для соответствующего компонента объекта производного типа;
Если родительский тип — ссылочный тип, то родительский и производный типы имеют один и тот же набор значений; существует пустое ссылочное значение для производного типа, которое по умолчанию является начальным значением этого типа;
Если существует явный спецификатор представления для родительского типа и если этот спецификатор расположен до (но не после) определения производного типа, соответствующий спецификатор представления неявно задан и для производного типа;
Некоторые подпрограммы, являющиеся операцйями над родительским типом, называются наследуемыми. Для каждой наследуемой подпрограммы родительского типа имеется соответствующая производная подпрограмма над производным типом. Существуют два сорта наследуемых подпрограмм. Во-первых, если родительский тип описан непосредственно в видимом разделе пакета, то подпрограмма, явно описанная непосредственно в этом видимом разделе, становится наследуемой после конца видимого раздела (если подпрограмма — операция над родительским типом). (Явное описание — это описание подпрограммы, описание переименования подпрограммы или конкретизация настройки.) Во-вторых, если родительский тип сам является производным типом и не описан в видимом разделе пакета, то подпрограмма, которая стала производной, и она не скрыта наследуемой подпрограммой первого сорта, является далее наследуемой.