Примечание. Относящиеся к выражениям универсального типа правила изложе­ны в разд. 4.10. Из этих правил следует, что именованное число имеет универсальный_ целый тип, если каждое содержащееся в выражении первичное имеет этот тип. Анало­гично, если каждое первичное имеет тип универсальный-вещественный, то именован­ное число имеет этот тип.

Примеры описаний чисел:

ПИ : constant: = 3.14159_26536; --вещественное

- - число

ДВА_ПИ : constant : = 2.0*ПИ; - - вещественное число

МАКСИМУМ : constant : = 500; -- целое число

СТЕПЕНЬ_16: constant : = 2 * * 16; -- целое 65_536

ОДИН, ONE, EINS: constant : = 1; - - три различных имени 1

  1. Типы и подтипы

Тип характеризуется набором значений и набором операций (точнее: операций типа или операций над типом).

Существует несколько классов типов. Скалярные типы — это целые и вещественные типы и типы, определенные перечислением своих значений; значения этих типов не имеют компонентов. Индексируемый и именуемый типы являются составными. Значение составного типа состоит из значений компонентов. Ссылочный тип — это тип, значения которого обеспечивают доступ к объектам. Личные типы - это типы, для которых полностью опре­деляется набор возможных значений, но непосредственный доступ к ним пользователей невозможен. Наконец, существуют задачные типы. (Личные типы описаны в гл. 7, задачные — в гл. 9, остальные - в гл. 3).

Именуемые и личные типы могут иметь специальные компоненты, на­зываемые дискриминантами, значения которых различают альтернативные формы значений каждого из этих типов. Если личный тип имеет дискрими­нанты, они известны пользователям типа. Следовательно, личный тип извес­тен только своим именем, своими дискриминантами, если они есть, и соот­ветствующим набором операций.

Набор возможных значений данного типа может зависеть от условия, которое называется ограничением (сюда же относятся случаи без ограниче­ния) ; значение удовлетворяет ограничению, если оно удовлетворяет соот­ветствующему условию. Подтип — это тип вместе с ограничением; говорят, что значение принадлежит подтипу, если оно принадлежит типу и удовлетво­ряет ограничению; данный тип называется базовым типом подтипа. Тип яв­ляется подтипом самого себя; такой подтип называется неограниченным; он соответствует условию, которое не налагает никаких ограничений. Базо­вым типом типа является он сам.

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

Для объектов некоторых типов определено начальное значение по умол­чанию; некоторые другие типы имеют выражения по умолчанию, опреде­ленные для части или всех своих компонентов. Некоторые операции над ти­пами и подтипами называются атрибутами; эти операции обозначаются фор­мой имени, описанной в разд. 4.1.4.

Термин подкомпонент используется в описании языка вместо термина компонент, чтобы указать компонент другого компонента или подкомпо­нента. Если нет других подкомпонентов, используется термин компонент.

Данный тип не должен иметь подкомпонентов, типом которых являет­ся он сам.

Имя класса типов используется в описании языка для квалификации объектов и значений, принадлежащих к типу рассматриваемого класса. На­пример, термин „индексируемый объект” используется для объекта индек­сируемого типа; аналогично термин „ссылочное значение” используется для значения ссылочного типа.

Примечание. Набор значений подтипа - это подмножество значений базового типа. Это подмножество не обязано быть собственным подмножеством; оно может быть пустым.

  1. О п и с а н и я типов

Описание типа объявляет тип.

описание—типа : : = полное—описание_типа

І неполное_описание_типа 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;

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

  1. array (1 . . 10) of BOOLEAN;

  2. array (1 . . 10) of BOOLEAN;

Если А и В описаны в групповом описании объектов

А,В: array (1 . . 10) of BOOLEAN;

то их типы (анонимные) тем не менее различны, так как это групповое описание объектов эквивалентно двум приведенным выше единичным описаниям.

Неполные описания типов используются для определения рекурсивных и взаимо­связанных типов (см. 3.8.1). Описания личных типов используются в спецификациях пакетов и в описаниях параметров настройки (см. 7.4 и 12.1).

  1. О п и с а н и е подтипов

Описание подтипа объявляет подтип.

описание_подтипа : : =

subtype идентификатор is указание_подтипа;

указание—подтипа : : — обозначение—типа [ограничение] обозначение_типа : : = имя_типа | имя_подтипа

ограничение : : = ограничение—Диапазона

I ограничение—плавающего—типа

I ограничение—фиксированного—типа

I ограничение—индекса

I ограничение—дискриминанта

Обозначение типа обозначает тип или подтип. Если обозначение типа — имя типа, то оно обозначает этот тип, а также соответствующий неограни­ченный подтип. Базовым типом, соответствующим обозначению типа, явля­ется, по определению, базовый тип типа или подтипа, указанного обозначе­нием типа.

Указание подтипа определяет подтип базового типа, соответствующего обозначению типа.

Если в указании подтипа после обозначения типа стоит ограничение ин­декса, то обозначение типа не должно обозначать подтип с уже ограничен­ным индексом. Аналогично, для ограничения дискриминанта обозначение типа не должно иметь ограничение дискриминанта.

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

  1. вначале предвыполняется ограничение;

  2. Ограничение проверяется на совместимость с типом или подтипом, заданным обозначением типа.

После предвыполнения ограничения получается условие, наложенное ограничением. (Правила предвыполнения ограничения таковы, что выраже­ния и диапазоны ограничений вычисляются при предвыполнении всех этих ограничений.) Правила определения совместимости даны в соответствую­щих разделах для каждой формы ограничения. Эти правила таковы, что ес­ли ограничение совместимо с подтипом, то наложенное ограничением усло­вие не может противоречить никакому условию, уже заданному для значе­ний этого подтипа. В противном случае возбуждается исключение 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

Примечание. Описание подтипа не определяет нового типа.

  1. К л а с с и ф и к а ц и я операций

Набор операций над типом включает явно описанные подпрограммы с параметром или результатом этого типа; такие подпрограммы необходимо описывать после описания типа.

Остальные операции неявно описываются сразу после каждого описа­ния соответствующего типа. К ним относятся базовые операции, предопре­деленные операции (см. 4.5) и литералы перечисления. Описанием произ­водного типа неявно задаются операции, включающие производные под­программы. Считается, что неявные описания операций расположены между описанием типа и последующим описанием, если таковое имеется. Неявные описания производных подпрограмм расположены последними.

Базовыми операциями являются:

  • Присваивание (в операторах присваивания и инициализациях), гене­ратор, проверка принадлежности и форма управления с промежуточной проверкой;

  • Именуемый компонент, индексируемый компонент и отрезок;

  • Квалификация (в квалифицированных выражениях), явное преобра­зование типа, и неявное преобразование значения типа универсальный _це- лый или универсальный_вещественный в соответствующее значение друго­го числового типа;

  • Числовой литерал (для универсального типа), литерал null (для ссы­лочного типа), строковый литерал, агрегат или атрибут.

Для каждого типа или подтипа Т определен следующий атрибут: T'BASE. Базовый тип Т. Этот атрибут допустим только в качестве префикса имени другого атрибута, например, T'BASE'FIKST.

Примечание. Каждый литерал - это операция, в результате выполнения которой вырабатывается соответствующее значение (см. 4.2). Подобно этому, агрегат - это операция, в результате выполнения которой вырабатывается значение составного ти­па (см. 4.3). Некоторые операции оперируют со значениями данного типа, например, предопределенные операции и некоторые подпрограммы и атрибуты. Некоторые опе­рации возвращают значение данного типа, например, литералы и некоторые функции, атрибуты и предопределенные операции. Присваивание - это операция, которая опери­рует с объектом и значением. В результате выполнения операции, соответствующей именуемому компоненту, индексируемому компоненту или отрезку, вырабатывает­ся объект или значение, обозначенное этой формой имени.

  1. Производные типы

Определение производного типа задает новый (базовый) тип, который наследует свойства родительского типа; новый тип называется производ­ным типом. Определение производного типа создает одновременно произ­водный подтип, являющийся подтипом производного типа.

определение—производного_типа : : =

new указание_подтипа

Указание подтипа после зарезервированного слова new определяет ро­дительский подтип. Родительский тип является базовым для родительского подтипа. Если для родительского подтипа существует ограничение, то по­добное ограничение существует и для производного подтипа; разница со­стоит только в том, что для ограничения диапазона и для ограничения пла­вающего или фиксированного типов, которое включает ограничение диапа­зона, значение каждой границы заменяется на соответствующее значение производного типа. Производный тип обладает следующими свойствами:

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

  • Для каждой базовой операции над родительским типом существует соответствующая базовая операция над производным типом. Допускается явное преобразование значения родительского типа в соответствующее зна­чение производного типа и наоборот, как поясняется в разд. 4.6;

  • Для каждого литерала перечисления или для каждой предопределен­ной операции над родительским типом существует соответствующая опера­ция над производным типом;

  • Если родительский тип — заданный тип, to для каждого входа роди­тельского типа существует соответствующий вход производного типа;

  • Если выражение по умолчанию существует для компонентов объекта, имеющего родительский тип, то то же самое выражение используется для соответствующего компонента объекта производного типа;

  • Если родительский тип — ссылочный тип, то родительский и произ­водный типы имеют один и тот же набор значений; существует пустое ссы­лочное значение для производного типа, которое по умолчанию является начальным значением этого типа;

  • Если существует явный спецификатор представления для родитель­ского типа и если этот спецификатор расположен до (но не после) опреде­ления производного типа, соответствующий спецификатор представления неявно задан и для производного типа;

  • Некоторые подпрограммы, являющиеся операцйями над родитель­ским типом, называются наследуемыми. Для каждой наследуемой подпро­граммы родительского типа имеется соответствующая производная под­программа над производным типом. Существуют два сорта наследуемых подпрограмм. Во-первых, если родительский тип описан непосредственно в видимом разделе пакета, то подпрограмма, явно описанная непосредст­венно в этом видимом разделе, становится наследуемой после конца види­мого раздела (если подпрограмма — операция над родительским типом). (Явное описание — это описание подпрограммы, описание переименования подпрограммы или конкретизация настройки.) Во-вторых, если родитель­ский тип сам является производным типом и не описан в видимом разделе пакета, то подпрограмма, которая стала производной, и она не скрыта на­следуемой подпрограммой первого сорта, является далее наследуемой.