вторник, 29 октября 2013 г.

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

   В первых двух статьях по массивам мы рассматривали одно и многомерные массивы в статическом варианте, но существует еще один вариант представления и одномерных и многомерных массивов и называется он - динамический.
   Для того, чтобы было понятней о чем идет речь, давайте сначала разберемся в чем заключается статичность и динамичность массивов?
    Ранее мы объявляли массивы указывая размерность от и до, например [0..3], то-есть длина такого массива определена, она конечна и уже не может быть изменена, в этом собственно и заключается статичность массива. Динамические же массивы не имеют фиксированного размера, и их длину - можно изменять во время выполнения программы. В данном случае при их объявлении, мы размер не указываем, а память под них выделяется при помощи функции SetLength. Давайте рассмотрим на примере, как все это отражается на синтаксисе. Объявим динамический одномерный массив вещественных чисел:

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

 var 
 a: array of Real; 

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

begin 
SetLength(a, 5);
// Выделение памяти для пяти элементов массива вещественных чисел от 0 до 4; 
end; 

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

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 на кнопке, объявляем наш массив:

var
a: array of Real; // Объявление переменной динамического массива; 
b: Integer; // Объявление переменных типа Integer;
begin 
b:=StrToInt(Edit1.Text); // Загружаем в переменную содержимое Edit1, (Размер массива); SetLength(a,b); // Определяем массиву динамическую переменную и размер - (переменная b); Label1.Caption:=IntToStr(length(a)); // Отображаем в Label1, присвоенный массиву размер; end;

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

   Ну как интересно? Значит продолжаем:

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

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

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

var
a: array of Real; // Объявление переменной динамического массива;
b: Integer; // Объявление переменных типа Integer;
c: Integer; 
begin 
Memo1.Lines.Clear; // Очищаем Memo от предыдущих результатов; 
c:=StrToInt(Edit1.Text); // Загружаем в переменную содержимое Edit1, (Размер массива); SetLength(a,c); // Определяем массиву динамическую переменную и размер - (переменная с);
for b:=0 to high(a) do
// От нуля до последнего его элемента (функция high) массива, выполнять:
begin 
a[b]:=StrtoFloat(Edit2.Text); 
// Циклом, в каждый элемент массива, от 0 до последнего элемента помещаем содержимое Edit2;
Memo1.Lines.Add(FloatToStr(a[b])); // Циклом заполняем в компоненте Memo1 и размер массива и содержание его элементов;
end; 
end; 

 4) Запускаем проект, вводим в первый Edit предполагаемый размер, а во второй значение для всех элементов, нажимаем на кнопку и любуемся результатом выведенном в Memo;

   Большая получается статья, но из песни слов не выкинешь, нужно сказать пару слов и о многомерных динамических массивах. У многомерных динамических массивов, при их описании вначале задается количество строк, затем длинна первого измерения, потом второго, третьего, четвертого и т.д. Причем у всех измерений, может быть различная длинна. Нумерация начинается с нуля.
   В качестве примера рассмотрим двумерный динамический массив (вопросы по остальным решаются по аналогии).

1) Объявляем многомерный динамический массив a:

var 
a: array of array of Integer; 

2) В начале - первой записью (SetLength(a, 5)) , указывается количество строк в массиве a , остальными - вида ( SetLength(a[0],3) ) - длинна каждой конкретной строки, где a - переменная массива, [0] - номер строки массива 3 - количество элементов, которые могут содержаться в строке (длинна строки).

begin 
SetLength(a, 5); // Массив будет состоять из шести строк (0..5);
SetLength(a[0],3); // Первая строка содержит четыре элемента;
SetLength(a[1], 4); // Вторая строка содержит пять элементов;
SetLength(a[2], 2); // Третья строка - 3 элемента;
SetLength(a[3], 5); // Четвертая строка - 6 элементов; 
SetLength(a[4], 1); // Пятая - 2 элементa; 
SetLength(a[5], 5); // Шестая - 6 элементов;
end;

  Если все это представить графически, то получится примерно следующее (см. рисунок ниже):



     3) Обращаемся к элементам массива, загружая в них числа:

var 
a: array of array of Integer; 
begin 
SetLength(a, 5); // Массив будет состоять из шести строк (0..5); 
SetLength(a[0], 3); // Первая строка содержит четыре элемента; 
SetLength(a[1], 4); // Вторая строка содержит пять элементов; 
SetLength(a[2], 2); // Третья строка - 3 элемента; 
SetLength(a[3], 5); // Четвертая строка - 6 элементов; 
SetLength(a[4], 1); // Пятая - 2 элементa; 
SetLength(a[5], 5); // Шестая - 6 элементов; 
a[0, 0]:=10; //Первому элементу, первого массива присваиваем значение - 10; 
a[1, 3]:=28; //Четвертому элементу, второго массива присваиваем значение - 28; 
a[2, 2]:=100; //Третьему элементу, третьего массива - 100; 
a[3, 4]:=8; //Пятому элементу, четвертого - 8; ... ... 
end; 

  Думаю здесь все должно быть понятно... А вот пример создания динамического многомерного массива состоящего из 6 строк, где все они имеют одинаковую длину, например - по 7 элементов.

var 
a: array of array of Integer; 
b: Integer; 
begin 
SetLength(a, 6); 
for b:=Low(a) to High(a) do 
SetLength(a[b], 7); 
end; 

  Наполнение данного массива значениями, предлагаю рассмотреть самостоятельно.

Комментариев нет:

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.