Spec-Zone.ru › Ada 2005
Справочник по Ada 2005

4.3.3 Массивы-агрегаты

В массиве-агрегате array_aggregate значение задаётся для каждого компонента массива, либо по позиции, либо по его индексу. Для позиционного массива-агрегата positional_array_aggregate компоненты задаются в порядке возрастания индексов, с последующим others, если необходимо, для оставшихся компонентов. Для именованного массива-агрегата named_array_aggregate компоненты идентифицируются значениями, охваченными discrete_choice.

Синтаксис

array_aggregate ::=
positional_array_aggregate | named_array_aggregate
positional_array_aggregate ::=
(выражение, выражение {, выражение})
| (выражение {, выражение}, others => выражение)
| (выражение {, выражение}, others => <>)
named_array_aggregate ::=
(ассоциация_компонента_массива {, ассоциация_компонента_массива})
ассоциация_компонента_массива ::=
список_выбора_дискретных_значений => выражение
| список_выбора_дискретных_значений => <>
N-мерный array_aggregate — это тот, который записывается как n уровней вложенных array_aggregate (или на нижнем уровне эквивалентные string_literal). В многомерном случае (n >= 2) array_aggregate (или эквивалентные string_literal) на n-1 более низких уровнях называются подмассивами окружающего n-мерного array_aggregate. Выражения на нижнем уровне подмассивов (или самого array_aggregate, если он одномерный) называются выражениями компонентов массива окружающего n-мерного array_aggregate.

Правила разрешения имён

Ожидаемый тип для array_aggregate (который не является подмассивом) должен быть единственным типом массива. Тип компонента этого типа массива — ожидаемый тип для каждого выражения компонента массива array_aggregate.
Ожидаемый тип для каждого discrete_choice в любом discrete_choice_list именованного массива-агрегата named_array_aggregate — это тип соответствующего индекса; соответствующий индекс для массива-агрегата, который не является подмассивом, — это первый индекс его типа; для (n–m)-мерного подмассива внутри массива-агрегата n-мерного типа соответствующий индекс — это индекс в позиции m+1.

Правила легальности

Массив-агрегат array_aggregate типа n-мерного массива должен быть написан как n-мерный array_aggregate.
Выбор others разрешен для array_aggregate только если для array_aggregate применима ограничение на индекс. Применимое ограничение на индекс — это ограничение, заданное определёнными контекстами, где разрешён array_aggregate и которое может использоваться для определения границ значения массива, задаваемого агрегатом. Каждый из следующих контекстов (и ни один другой) определяет применимое ограничение на индекс:
  • Для explicit_actual_parameter, explicit_generic_actual_parameter, выражение оператора возврата, object_declaration или default_expression (для параметра или компонента), когда номинальный подтип соответствующего формального параметра, формального параметра обобщённого типа, объекта функции возврата, объекта или компонента является ограниченным подтипом массива, применимым ограничением на индекс является ограничение подтипа;
  • Для выражения оператора присваивания assignment_statement, где имя обозначает переменную массива, применимым ограничением на индекс является ограничение переменной массива;
  • Для операнда qualified_expression, subtype_mark которого обозначает ограниченный подтип массива, применимым ограничением на индекс является ограничение подтипа;
  • Для выражения компонента в агрегате, если номинальный подтип компонента является ограниченным подтипом массива, применимым ограничением на индекс является ограничение подтипа;
  • Для выражения в скобках, применимым ограничением на индекс является, если таковое существует, ограничение, определённое для выражения.
Применимое ограничение на индекс применяется к массиву-агрегату, который появляется в таком контексте, а также к любым подмассивам. В случае явного фактического параметра (или выражения по умолчанию) для вызова формальной подпрограммы обобщённого типа, применимое ограничение на индекс не определено.
Список выбора дискретных значений discrete_choice_list ассоциации компонента массива array_component_association разрешается иметь выбор дискретных значений discrete_choice, который является нестатическим выражением или является дискретным диапазоном, который определяет нестатический или нулевой диапазон, только если это единственный выбор дискретных значений в его списке, и в агрегате массива существует только одна ассоциация компонента массива.
В именованном агрегате массива named_array_aggregate с более чем одним выбором дискретных значений discrete_choice не допускается, чтобы два выбора дискретных значений охватывали одно и то же значение (см. 3.8.1); если выбора others нет, то в совокупности выбранные дискретные значения должны точно охватывать непрерывную последовательность значений соответствующего типа индекса.
Подмассив нижнего уровня многомерного array_aggregate данного типа массива может быть string_literal только если тип компонента массива является типом символа; каждый символ такого string_literal должен соответствовать defining_character_literal типа компонента.

Статическая семантика

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

Динамическая семантика

Вычисление агрегата_массива заданного типа массива происходит в два этапа:
1.
Любые дискретные_выборы этого агрегата и его подмножеств оцениваются в произвольном порядке и преобразуются в соответствующий тип индекса;
2.
Элементы-выражения массива агрегата оцениваются в произвольном порядке, а их значения преобразуются в тип подкомпонента массива; выражение элемента массива вычисляется один раз для каждого связанного компонента.
Каждое выражение в ассоциации_компонента_массива определяет значение для связанных компонентов. Для ассоциации_компонента_массива с <>, связанные компоненты инициализируются по умолчанию, как для самостоятельного объекта типа компонента (см. 3.3.1).
Пределы диапазона индекса агрегата_массива (включая подмножество) определяются следующим образом:
  • Для агрегата_массива с выбором others границы соответствуют соответствующему диапазону индексов из применимого ограничения индекса;
  • Для массива_позиционного_агрегата (или эквивалентной строковой_литерали) без выбора others нижняя граница соответствует соответствующему диапазону индексов в применимом ограничении индекса, если оно определено, или типу индекса, если нет; в любом случае верхняя граница определяется из нижней границы и количества выражений (или длины строковой_литерали);
  • Для агрегата_именованного_массива без выбора others границы определяются наименьшими и наибольшими значениями индекса, покрытыми любым списком_дискретных_выборов.
Для агрегата_массива выполняется проверка совместимости диапазона индексов, определяемого его границами, с соответствующим типом индекса.
Для агрегата_массива с выбором others выполняется проверка, что для значения индекса, находящегося за пределами границ, определяемых применимым ограничением индекса, не указано выражение.
Для многомерного агрегата_массива выполняется проверка, что все подмножества, соответствующие одному индексу, имеют одинаковые границы.
Исключение Constraint_Error генерируется, если любая из вышеуказанных проверок завершается неудачей.
ПРИМЕЧАНИЯ
10 В агрегате_массива позиционная запись может использоваться только с двумя или более выражениями; одно выражение в скобках интерпретируется как выражение в скобках. Агрегат_именованного_массива, такой как (1 => X), может использоваться для указания массива с одним компонентом.

Примеры

Примеры агрегатов массивов с позиционными ассоциациями:
(7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
Table'(5, 8, 4, 1, others => 0) -- см. 3.6
Примеры агрегатов массивов с именованными ассоциациями:
(1 .. 5 => (1 .. 8 => 0.0)) -- двухмерный
(1 .. N => new Cell) -- N новых ячеек, в частности для N = 0
Table'(2 | 4 | 10 => 1, others => 0)
Schedule'(Mon .. Fri => True, others => False) -- см. 3.6
Schedule'(Wed | Sun => False, others => True)
Vector'(1 => 2.5) -- массив с одним компонентом
Примеры двухмерных агрегатов массивов:
-- Три агрегата для одного и того же значения подтипа Matrix(1..2,1..3) (см. 3.6):
((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
(1 => (1.1, 1.2, 1.3), 2 => (2.1, 2.2, 2.3))
(1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3))
Примеры агрегатов в качестве начальных значений:
A : Table := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0); -- A(1)=7, A(10)=0
B : Table := (2 | 4 | 10 => 1, others => 0); -- B(1)=0, B(10)=1
C : constant Matrix := (1 .. 5 => (1 .. 8 => 0.0)); -- C'Last(1)=5, C'Last(2)=8
D : Bit_Vector(M .. N) := (M .. N => True); -- см. 3.6
E : Bit_Vector(M .. N) := (others => True);
F : String(1 .. 1) := (1 => 'F'); -- агрегат с одним компонентом: то же, что и "F"
Пример агрегата массива с выбором others по умолчанию и с применимым ограничением индекса, заданным окружающим записянным агрегатом:
Buffer'(Size => 50, Pos => 1, Value => String'('x', others => <>)) -- см. 3.7


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API