Ада-95. Компилятор GNAT

       

Типы неограниченных массивов (unconstrained array), предопределенный тип String


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

В дополнение к таким типам, Ада позволяет описывать типы массивов, которые не имеют четко определенного диапазона для индексных значений, когда описание типа не определяет границ массива. Поэтому такие массивы называют неограниченными массивами (unconstrained array).

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

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

Этот механизм удобно использовать в случаях когда массив произвольного размера необходимо передать в подпрограмму как параметр.

Примером описания неограниченного массива целых чисел может служить следующее:

type Numbers_Array is array (Positive range <>) of Integer;

Символы "<>" указывают, что диапазон значений индекса должен быть указан при описании объектов типа Numbers_Array. Переменная такого типа может быть описана следующим образом:

Numbers : Numbers_Array (1..5) := (1, 2, 3, 4, 5);

Здесь, при описании переменной Numbers предусматривается ограничение (constraint) размеров массива - указывается диапазон значений индекса - (1..5).

Пакет Standard предоставляет предопределенный тип String, который описывается как неограниченный массив символов:

type String is array (Positive range <>) of Character;

Таким образом, тип String может быть использован для описания обширного класса символьных массивов, которые идентичны во всем, кроме количества элементов в массиве.




Также как и в предыдущем примере описания переменной Numbers, для создания фактического массива типа String, мы должны предусмотреть ограничение диапазона возможных значений индекса:

My_Name : String (1..20);

Здесь, ограничение диапазона индексных значений находится в диапазоне 1..20. Преимущество такого подхода в том, что все описанные строки имеют один и тот же тип, и могут, таким образом, использоваться как параметры подпрограмм. Такой дополнительный уровень абстракции позволяет более общее использование подпрограмм обработки строк.

Необходимо заметить, что для инициализации объектов типа String, можно использовать агрегаты, поскольку тип String, по сути, является массивом символов. Однако, более цивилизованным способом будет использование строковых литералов. Так, вышеописанную переменную My_Name, можно инициализировать следующим образом:

My_Name := "Alex ";

Следует учесть, что в приведенном примере, строковый литерал, указывающий имя, необходимо дополнить пробелами, чтобы его размер совпадал с размером описанной переменной. В противном случае, компилятор может выдать предупреждение о возбуждении исключения Constraint_Error во время выполнения программы.

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

Some_Name : String := "Vasya Pupkin"; Some_Saying : constant String := "Beer without vodka is money to wind!";

Для обработки каждого элемента переменной, которая порождается при использовании типа неограниченного массива, требуется использование таких атрибутов типа массив, как A'Range, A'First и т.д., поскольку не известно какие индексные значения будет иметь обрабатываемый массив.

My_Name : String (1..20); My_Surname : String (21..50);

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


Содержание раздела