2 type Name = array of Base type; // Динамический массив

3 Name : array of const; // Открытый различный массив
Name : Array type; // Открытый динамический массив

Описание
Ключевое слово Array обеспечивает одномерные и многомерные массивы данных.

Delphi имеет три основных типа массивов :

1. Статические массивы

Они определены установленными, неизменяемыми размерами. Они могут быть одномерными или многомерными — последний является массивом массивов (массивов и т.д). Размер и диапазон такого многомерного массива всегда даются для самого высокого, крайнего левого массива — родительского массива.

Размер каждого измерения определен двумя способами, которые могут быть свободно смешаны в многомерном массиве :

Index type, где Index целое число, обычно Byte или Word. Диапазон этого типа определяет диапазон измерения. Например, Byte дает дипазон 0..255.

Ordinal..Ordinal Альтернативно, диапазон каждого измерения может быть задан предписанными порядковыми значениями, типа 22..44.

2. Динамические массивы

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

устанавливает размер одномерного массива dynArray в 5 элементов. При этом будет распределена память.

Все динамические массивы начинаются с индекса = 0.

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

3. Открытые массивы

И статические и динамические массивы можно передать подпрограммам как параметры. Если определение параметра массива не имеет никакого диапазона (то есть, динамический тип массива), то вы должны, как это ни парадоксально передавать статический массив как параметр. Такой массив упоминается как Открытый массив. Delphi передает длину как скрытый параметр для подпрограммы.

Открытый массив также может быть определен типом значения константы. Это называют Различным (Variant) открытым массивом — это, главным образом, используется для разрешения передачи подпрограмме переменного числа значений аргументов.

Для передачи Динамического массива ссылкой, массив и подпрограммное определение массива должны быть через определение типов массива. См. код для примера.

ПримечанияИспользуйте Copy для копирования одного массива в другой. Но будьте осторожны — это копирует только первое, самое высокое измерение — новый массив будет все еще относиться к элементам подмассивов.Похожие команды
Copy Создает копию части строки или части массива

High Возвращает самое высокое значение типа или переменной

Length Возвращает число элементов в массиве или строке

Low Возвращает самое низкое значение типа или переменной

SetLength Изменяет размер строки или размер динамического массива

Slice Создает часть массива с параметром "Открытый Массив"

Объявляя статический массив в Delphi, мы указывали его размерность от и до, например [0..3], то есть длина такого массива определена, она конечна и уже не может быть изменена, в этом собственно и заключается статичность массива.

Динамические же массивы в Delphi не имеют фиксированного размера, и их длину — можно изменять во время выполнения программы. В данном случае при их объявлении, мы размер не указываем, а память под них выделяется при помощи функции SetLength.

Давайте рассмотрим на примере, как все это отражается на синтаксисе. Объявим динамический одномерный массив вещественных чисел:

1) в разделе var просто определяем переменную и ее тип:

2) Для определения размерности, воспользуемся функцией SetLength. Чтобы было понятней, эта функция имеет два параметра. Первый это переменная нашего массива — a, второй — его длина , допустим пусть будет — 5:

Чтобы при необходимости высвободить из по массива память, достаточно прописать:

a:=nil; — nil в Delphi означает отсутствие значения.

Для непосредственной работы с динамическими массивами, существует ряд функций, это:

  • функция Length— определяющая длину массива;
  • функция High— возвращающая наибольший индекс массива;
  • функция Lowвозвращающая наименьший индекс массива;

Продемонстрируем теперь на примере, работу функции lehgth и возможность изменения размера массива. Для этого напишем программу, в которой мы в Edit будем вводить желаемый размер массива, и по нажатию кнопки, label нам покажет, что введенный размер, нашему массиву присвоен.

1) Кидаем на форму компоненты Label, Button и Edit;

2) Свойство Caption у label и Text у Edit1 ставим в 0, a в свойстве Caption у Button запишем фразу: — Задать размер;

3) Создаем обрабочик событий OnClick на кнопке, объявляем наш массив и записываем следующий код:

4) Запускаем проект, и убеждаемся, что можем теперь задавать практически любой размер нашему массиву, вводя числа в Edit, и нажимая на кнопку.

Теперь продемонстрируем на примере один из способов задания размера и автоматического заполнения элементов динамических массивов. Напишем программу, в которой в первый Edit, мы будем вводить размер массива, во второй Edit значение его элементов. А по нажатию на кнопку, компонент Мемо — отобразит нам, как размерность массива, так и содержание его элементов.

1) Кидаем на форму 2 компонента Edit, один — Button и один — Memo;

2) В свойстве Text у Edit1 и Edit2 — записываем 0, очищаем свойство Lines компонента Memo, а в свойство Caption у Button запишем слово: Вычислить;

3) Создаем обработчик событий OnClick на Button, и пишем следующее:

Буду описывать здесь процесс выполнения различных работ.

Страницы

четверг, 1 марта 2012 г.

Динамический массив в Delphi

Как видим , мы просто говорим Delphi, что нам нужен одномерный массив типа Integer, а об его размере мы скажем когда нибудь потом.

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

2. Для выделения памяти для динамического массива в Delphi используется процедура SetLength:

После вызова этой процедуры будет выделена память для 20 элементов массива, которые будут проиндексированы от 0 до 19 (обратите внимание: индексирование начинается с нуля, а не с единицы!).
После этого можно работать с динамическим массивом- присваивать ему значения, производить с элементами различные вычисления, вывод на печать и т.д.
Например

da_MyArray[0] := 5 ;
da_MyArray[9] := 9 ;
da_MyArray[1] := da_MyArray[0]+ da_MyArray[9] ;

3. Как только динамический массив был распределен, вы можете передавать массив стандартным функциям Length, High, Low и SizeOf Функция Length возвращает число элементов в динамическом массиве, High возвращает самый высокий индекс массива (то есть Length — 1), Low возвращает 0. В случае с массивом нулевой длины наблюдается интересная ситуация: High возвращает -1, а Low — 0, получается, что High меньше Low. 🙂 Функция SizeOf всегда возвращает 4 — длина в байтах памяти указателя на динамический массив

iHigh := High (da_MyArray3);
iLow := Low (da_MyArray3);

4. Доступ к данным динамических массивов с помощью низкоуровневых процедур типа ReadFile или WriteFile , или любых других подпрограмм, получающих доступ сразу ко всему массиву, часто выполняется неправильно. Для обычного массива (его часто называют также статическим массивом — в противоположность динамическому массиву) переменная массива тождественна его данным. Для динамического массива это не так — переменная это указатель. Так что если вы хотите получить доступ к данным динамического массива — вы не должны использовать саму переменную массива, а использовать вместо неё первый элемент массива.

правильно
WriteFile(FHandle, da_MyArray02[0], Length(da_MyArray02), dwTemp, nil )

неправильно
WriteFile(FHandle, da_MyArray02, Length(da_MyArray02), dwTemp, nil )

5. Рассмотрим пример присваивания динамических массивов одного другому

После этих манипуляций da_A[0] равно 4. Дело в том , что при присвоении da_A:=da_B не происходит копирование т.к. da_A, da_B, это всего лишь указатели на область памяти. Для копирования необходимо использовать функцию Copy.

6. Рассмотрим пример копирования динамических массивов с использованием функции Copy

После этих манипуляций da_A[0] равно 3. После функции Copy da_A и da_B указывают на разные области памяти, поэтому при изменении da_B в da_A ничего не происходит и его значения остаются неизменными.

7. Динамические массивы (например, array of Integer ) в Delphi в памяти расположены следующим образом. Библиотека runtime добавляет специальный код, который управляет доступом и присваиваниями. В участке памяти ниже адреса, на который указывает ссылка динамического массива, располагаются служебные данные массива: два поля — число выделенных элементов и счётчик ссылок (reference count).

Расположение динамического массива в памяти

Если, как на диаграмме выше, N — это адрес в переменной динамического массива, то счётчик ссылок массива лежит по адресу N — 8 , а число выделенных элементов (указатель длины) лежит по адресу N — 4 . Первый элемент массива (сами данные) лежит по адресу N .
Для каждой добавляемой ссылки (т.е. при присваивании, передаче как параметр в подпрограмму и т.п.) увеличивается счётчик ссылок, а для каждой удаляемой ссылки (т.е. когда переменная выходит из области видимости или при переприсваивании или присваивании nil) счётчик уменьшается.

8. Написал 2 программы, которые иллюстрируют теоретические сведения по динамическим массивам , приведенным в посте.

Окно программы примера 1

Окно программы примера 2

Скачать программы- примеры с исходными кодами здесь : Dynamic-Array.rar

Использовались функции SetLength, High, Low, Length, SizeOf, OpenFile, WriteFile, SetFilePointer, ReadFile, CloseHandle, ShellExecute, IntToStr, IntToHex, Integer, Copy, Ptr