17.1 Создание массива

Не волнуйтесь о большом количестве опций для функции make-array. Все что действительно необходимо, это список размерностей. Остальные же опции служат для относительно эзотерических программ.

[Функция] make-array dimensions &key :element-type :initial-element :initial-contents :adjustable :fill-pointer :displaced-to :displaced-index-offset

Это базовая функция для создания массивов. Аргумент dimensions должен быть списком неотрицательных целых чисел, которые являются измерениями массива. Длина списка является размерностью массива. Каждое измерение должно быть меньше чем array-dimension-limit, и произведение всех измерений должно быть меньше array-total-size-limit. Следует отметить, что если dimensions nil, тогда создаётся массив с нулевым количеством измерений. По соглашению, при создании одномерного массива, размер измерений может быть указан как одиночное целое число, а не список целых чисел.

Реализация Common Lisp’а может иметь ограничение на ранг массива, но это ограничение должно быть меньше 7. Таким образом, любая Common Lisp программа может использовать массивы с рангом меньшим или равным 7.

Для make-array существуют следующие именованные параметры:

Если make-array вызывается без указания аргументов :adjustable, :fill-pointer и :displaced-to, или указания их в nil, тогда получаемый массив гарантированного будет простым (смотрите раздел 2.5).

X3J13 voted in June 1989 to clarify that if one or more of the :adjustable, :fill-pointer, and :displaced-to arguments is true, then whether the resulting array is simple is unspecified.

Вот несколько примеров использования make-array:

;;; Создание одномерного массива с пятью элементами.
(make-array 5)

;;; Создание двумерного массива, 3 на 4, с четырёхбитными элементами.
(make-array ’(3 4) :element-type ’(mod 16))

;;; Создание массива чисел с плавающей точкой.
(make-array 5 :element-type ’single-float))

;;; Создание соединённого массива.
(setq a (make-array ’(4 3)))
(setq b (make-array 8 :displaced-to a
                      :displaced-index-offset 2))
;;; В таком случае:
        (aref b 0)  (aref a 0 2)
        (aref b 1)  (aref a 1 0)
        (aref b 2)  (aref a 1 1)
        (aref b 3)  (aref a 1 2)
        (aref b 4)  (aref a 2 0)
        (aref b 5)  (aref a 2 1)
        (aref b 6)  (aref a 2 2)
        (aref b 7)  (aref a 3 0)

Последний пример связи между массивами зависит от того факта, что элементы массивов хранятся построчно. Другими словами, индексы элментов массива упорядочены лексикографически.


[Константа] array-rank-limit

Значение array-rank-limit является положительным целым, которое обозначает (невключительно) наивысший возможный ранг массива. Это значение зависит от реализации, но не может быть меньше 8. Таком образом каждая реализация Common Lisp’а поддерживает массивы, ранг которых лежит между 0 и 7 (включительно). (Разработчикам предлагается сделать это значение большим настолько, на сколько это возможно без ущерба в производительности.)


[Константа] array-dimension-limit

Значение array-dimension-limit является положительным целым, которое обозначает (невключительно) наивысший возможный размер измерения для массива. Это значение зависит от реализации, но не может быть меньше 1024. (Разработчикам предлагается сделать это значение большим настолько, на сколько это возможно без ущерба в производительности.)

X3J13 voted in January 1989 to specify that the value of array-dimension-limit must be of type fixnum. This in turn implies that all valid array indices will be fixnums.


[Константа] array-total-size-limit

Значение array-total-size-limit является положительным целым, которое обозначает (невключительно) наивысшее возможное количество элементов в массиве. Это значение зависит от реализации, но не может быть меньше 1024. (Разработчикам предлагается сделать это значение большим настолько, на сколько это возможно без ущерба в производительности.)

На практике предельный размер массива может зависеть от типа элемента массива, в таком случае array-total-size-limit будет наименьшим из ряда этих размеров.


[Функция] vector &rest objects

Функция vector служит для создания простых базовых векторов с заданным содержимым. Она является аналогом для функции list.

(vector a1 a2 ... an)
    (make-array (list n) :element-type t
             :initial-contents (list a1 a2 ... an))