Требование фиксированного размера для массива-параметра часто является чрезмерно сдерживающим фактором. Подпрограмма может работать с массивами произвольной длины. Для этой цели в язык Delphi введены открытые массивы-параметры.
Особенности:
1. Открытый массив-параметр описывается с помощью словосочетания array of, при этом границы массива опускаются:
function Average(A: array of Double): Double; var I: Integer; begin Result:= 0; for I:= Low (A) to High (A) do Result:= Result + A[I]; Result:= Result / Length (A); end;
2. Внутри подпрограммы Average нижняя граница открытого массива A равна нулю (Low (A) = 0), а вот значения верхней границы (High (A)) и длины массива (Length (A)) неизвестно и выясняется только на этапе выполнения программы.
3. Пример использования функции Average:
var Statistics: array [1..10] of Double; Mean: Double; begin... Mean:= Average(Statistics); Mean:= Average([0, Random, 1]);... end;Во втором операторе открытый массив конструируется в момент вызова функции Average. Конструктор открытого массива представляет собой заключенный в квадратные скобки список выражений. В выражениях могут использоваться константы, переменные и функции. Тип выражений должен быть совместим с типом элементов массива. Конструирование открытого массива равносильно созданию и инициализации временной переменной.
4. Открытые массивы могут быть переданы в подпрограммы только по значению или как параметры-константы.
Динамические массивы
Основное отличие динамических массивов от статических заключается в том, что они хранятся в динамической памяти. Этим и обусловлено их название. Чтобы понять, зачем они нужны, рассмотрим пример:
На этапе написания программы иногда невозможно предугадать, какие именно объемы данных захочет обрабатывать пользователь. Размер динамического массива можно изменять во время работы программы.
Динамический массив объявляется без указания границ: array of baseType
Например: var DynArray: array of Integer;
Работа с динамическими массивами:
1. Переменная DynArray представляет собой ссылку на размещаемые в динамической памяти элементы массива.
2. Изначально память под массив не резервируется, количество элементов в массиве равно нулю, а значение переменной DynArray равно nil.
3. Создание динамического массива (выделение памяти для его элементов) осуществляется процедурой SetLength, например:
SetLength (DynArray,50)
4. Изменение размера динамического массива производится этой же процедурой.
При увеличении размера массива значения всех его элементов сохраняются, а добавленные элементы не инициализируются никаким значением (в общем случае их значения случайны). При этом последовательность действий такова: выделяется новый блок памяти, значения элементов из старого блока копируются в новый, старый блок памяти освобождается. При уменьшении размера динамического массива лишние элементы теряются.
5. Элементы динамического массива всегда индексируются от нуля. Доступ к ним ничем не отличается от доступа к элементам обычных статических массивов:
6. К динамическим массивам применимы функции Low, High и Length, возвращающие минимальный, максимальный индексы и длину массива соответственно. Для динамических массивов функция Low всегда возвращает 0.
7. Освобождение памяти, выделенной для элементов динамического массива, осуществляется установкой длины в значение 0 или присваиванием переменной-массиву значения nil (оба варианта эквивалентны):
SetLength (DynArray, 0); // Эквивалентно: DynArray:= nil;
Однако вовсе необязательно по окончании использования динамического массива освобождать выделенную память, поскольку она освобождается автоматически при выходе из области действия переменной-массива.
8. Для работы с динамическими массивами вы можете использовать знакомую по строкам функцию Copy. Она возвращает часть массива в виде нового динамического массива.
9. Для многомерных динамических массивов:
Var A: array of array of Integer; begin... SetLength (A, 100, 20); ...end.