Динамические массивы |
Вверх Предыдущий Следующий |
Начиная с версии 1.1, Free Pascal также поддерживает, динамические массивы: В этом случае диапазон массива не указывается, как в следующем примере: Type TByteArray = Array of Byte; При объявлении переменной типа динамический массив начальная длина массива равна нулю. Фактическая длина массива должна быть установлена стандартной функцией SetLength, которая выделит память необходимую для размещения элементов массива в куче. Следующий пример установит длину массива равную 1000: Var A : TByteArray;
begin SetLength(A,1000); После вызова SetLength, допустимыми индексами массива будут числа от 0 до 999: индексация массива всегда начинается с нуля. Обратите внимание, что длина массива задается в элементах, а не в байтах выделяемой памяти (хотя они могут быть и одинаковыми). Объем выделенной памяти равняется размеру массива умноженном на размер одного элемента в массиве. Память будет освобождена при выходе из текущей процедуры или функции. Также есть возможность изменить размер массива: в этом случае будет сохранено настолько много элементов сколько поместится в новом размере массива. Размер массива может быть установлен в ноль, это эффективный способ сбросить переменную. Попытка получить доступ к элементу массива с индексом, выходящим за границы объявленного диапазона, всегда генерирует ошибку периода выполнения. Для динамических массивов ведется подсчет ссылок: присвоение одной переменной типа динамический массив, другой переменной, позволит обеим переменным указывать на тот же самый массив. В отличие от AnsiStrings, присвоение значения одному элементу массива будет отражено и в другом: не делается никакой копии массива при записи. Рассмотрите следующий пример: Var A,B : TByteArray;
begin SetLength(A,10); A[0]:=33; B:=A; A[0]:=31; После второго присвоения первый элемент в B будет также содержать 31. Это также можно заметить по выводу следующего примера: program testarray1;
Type TA = Array of array of Integer;
var A,B : TA; I,J : Integer;
begin Setlength(A,10,10); For I:=0 to 9 do For J:=0 to 9 do A[I,J]:=I*J; For I:=0 to 9 do begin For J:=0 to 9 do Write(A[I,J]:2,' '); Writeln; end; B:=A; Writeln; For I:=0 to 9 do For J:=0 to 9 do A[9-I,9-J]:=I*J; For I:=0 to 9 do begin For J:=0 to 9 do Write(B[I,J]:2,' '); Writeln; end; end. Выводом этой программы будет матрица чисел, а затем будет выведена такая же матрица, но зеркально. Как отмечалось ранее, для динамических массивов ведется подсчет ссылок: если в одном из предыдущих примеров A выйдет за границы области а B нет, то массив ещё не будет освобожден: счетчик ссылок А (и B) уменьшится на 1. Как только счетчик ссылок достигнет нуля, память, выделенная для содержания массива, освобождается. Вызов SetLength установит счетчик ссылок на указанный массив в 1, если он больше, то после вызова SetLength переменные динамического массива больше не будут указывали на одну и ту же память. program testunique;
Type TA = array of Integer;
var A,B : TA; I : Integer; begin Setlength(A,10); For I:=0 to 9 do A[I]:=I; B:=A; SetLength(B,6); A[0]:=123; For I:=0 to 5 do Writeln(B[I]); end. Также возможно скопировать и/или изменить размер массива с помощью стандартной функции Copy, которая действует как функция копирования для строк: program testarray3;
Type TA = array of Integer;
var A,B : TA; I : Integer; begin Setlength(A,10); For I:=0 to 9 do A[I]:=I; B:=Copy(A,3,6); For I:=0 to 5 do Writeln(B[I]); end. Функция Copy скопирует 6 элементов массива в новый массив. Начиная с элемента по индексу 3 (то есть четвертого элемента) массива. Функция Length возвратит число элементов в массиве. Функция Low для динамического массива будет всегда возвращать 0, а функция High возвратит значение Length-1, то есть, значение самого большого позволенного индекса массива. |