Массив массива записей - PullRequest
1 голос
/ 28 марта 2019

Мне нужно создать постоянный массив из постоянного массива записей, где я могу ссылаться на каждый элемент внешнего массива по номеру.

Я пробовал:

A : constant array (0 .. 3) of B := (B1, B2, B3, B4) 

где B - массив записей, а B1, B2, B3, B4 - постоянные массивы типа B.

Но когда я это делаю, я получаю ошибку: «Неограниченный тип элемента в объявлении массива»

type C is record
   a : Integer := 0;
   b : Integer := 0;
   c : Integer := 0;
   d : Integer := 0;
end record;

type B is array (Natural range <>) of C;

B1 : constant B := (0, 0, 0, 0);
B2 : constant B := (2, 0, 2, 0);
B3 : constant B := (0, 1, 0, 1);
B4 : constant B := (2, 1, 2, 1);

A : constant array (0 .. 3) of B := (B1, B2, B3, B4);

Я надеялся использовать A, чтобы иметь возможность ссылаться на B1, B2, B3, B4 в числовом формате, например:

A (1) возвращает B1

A (2) возвращаетB2

и так далее ...

(Я прошу прощения, если я использую неправильные термины. Я немного новичок в Аде и учусь методом проб и ошибок ...)

Ответы [ 2 ]

2 голосов
/ 28 марта 2019

То, что очевидно для вас, не очевидно для компилятора, то есть все ваши элементы B имеют четыре элемента.

Для доступа к элементу A (3) (2) он (или язык Ada) хочет бытьв состоянии сделать очень простую арифметику (2 + 3 * 4) * (размер целого числа).Массив B (который является неограниченным) сделает это вычисление слишком сложным.Полученный машинный код должен был бы добавить размеры A (0), A (1), A (2) только для того, чтобы добраться до A (3) (0).Конечно, вы можете себе представить время, которое потребуется для гораздо больших длин массива, например, только для доступа к элементу A (1234) (5678).

Именно поэтому разработчикам Ada разумно требовалось иметь всегда массивы ограничено типов.Для вашей проблемы вы можете решить ее, определив subtype BL4 is B (0 .. 3); и использовать BL4 вместо B для B1, B2, B3, B4 и A.

2 голосов
/ 28 марта 2019

Ваша проблема в том, что B - это массив без ограничений:

type B is array (Natural range <>) of C;

Это хорошо для B1 : constant B := (0, 0, 0, 0);, так как определение константы создает новый анонимный тип с диапазоном, взятым из Right-Hand-Side.

Это, однако, не подходит для A.Компилятор должен знать размер элементов массива, но не может, когда элемент (B в этом случае) не ограничен.Кроме того, ограничения ('First, 'Last и т. Д.) Должны быть одинаковыми для всех элементов.

Вы можете изменить определение B, чтобы оно было ограничено:

type B is array (Natural range 1..4) of C;

Это заставит все ваши B1, B2 и т. Д. Всегда иметь четыре элемента, что у вас уже есть в вашем примере.

Кроме того, если вы хотите, чтобы A(1) вернулB1, вы должны изменить диапазон A, чтобы начать с 1:

A : constant array (1 .. 4) of B := (B1, B2, B3, B4);
...