В этом видеоуроке я наглядно и продробно обьяснил что такое многомерные массивы (матрицы):
Скачайте прямо сейчас бесплатно остальные видеоуроки по Delphi в одном архиве: СКАЧАТЬ БЕСПЛАТНО!
В Delphi доступны два способа объявления многомерных массивов:
ИмяМассива: array[Диапазон_1, Диапазон_2] of ТипДанных; ИмяМассива: array[Диапазон_1] ofarray[Диапазон_2] of ТипДанных;
Подобно тому, как одномерные массивы упрощают работу с большим количеством переменных, многомерные массивы упрощают работу с большим количеством одномерных массивов. Например, очень простой двухмерный массив можно использовать для хранения таблицы умножения и при необходимости считывания из нее соответствующих значений.
Все переменные и массивы, которые мы использовали до сих пор. были статическими. Они называются статическими потому, что их размер известен во время компиляции, память для них резервируются в стеке, и они создаются и уничтожаются автоматически.
Динамические массивы существенно отличаются от статических:
Память для динамических массивов выделяется вручную во время выполнения.
Первый индекс динамического массива всегда равен О.
Память для динамических массивов всегда резервируется в куче.
Куча — это область основной памяти, которая ограничена только размером доступной на компьютере виртуальной памяти. Если требуется хранить в массиве очень большой объем данных, следует использовать динамический массив, поскольку размеры статических массивов ограничены размером стека.
Для объявления динамических массивов используется следующий синтаксис:
ИмяМассива: array of ТипДанных;
Во время объявления динамического массива он не содержит никаких данных, и никакая память для него не резервируется. Чтобы зарезервировать память для динамического массива, необходимо вызвать функцию SetLength. Она принимает два параметра. При работе с динамическими массивами первым параметром должно служить имя массива, а вторым — новый размер массива.
01.program Project1;
02.{$APPTYPE CONSOLE}
03.uses
04.SysUtils;
05.var
06.students: array of string;
07.stNumber: Integer;
08.cnt: Integer;
09.begin
10.Write('Number of students: ');
11.ReadLn(stNumber);
12.SetLength(students, stNumber);
13.{ Get student names from the user }
14.for cnt := Low(students) to High(students) do
15.begin
16.Write('Student: ');
17.ReadLn(students[cnt]);
18.if students[cnt] = 'end' then Break;
19.end;
20.ReadLn;
21.end.
Для определения размера динамического массива можно использовать функцию Length, которая принимает только один параметр — имя динамического массива. Она возвращает общее количество элементов динамического массива. Индекс последнего элемента, возвращаемый функцией High, равен Length-1.
1.var
2.DynArray: array of string; i: Integer;
3.begin
4.for i := Low(DynArray) to High(DynArray) do ;
5.for i ;= 0 to Length(DynArray) - 1 do ;
6.ReadLn;
7.end.
Оба цикла for выполняются одинаковое количество раз, поэтому конкретную форму синтаксиса можете выбирать по своему усмотрению. В целях соблюдения единообразия рекомендуется использовать функции High и Low в циклах, подобных этим, и функцию Length, когда требуется определить количество элементов в динамическом массиве. Обратите внимание, что оба оператора цикла for завершаются символами точки с запятой. Это означает, что эти циклы не выполняют никаких действий. Если в реальном приложении окажется, что цикл не работает должным образом, убедитесь, что за зарезервированным словом do не следует символ точки с запятой. Ниже приведена иллюстрация этой программной ошибки:
01.program Projectl;
02.{$АРРТУРЕ CONSOLE)
03.uses
04.SysUtils;
05.var
06.i: Integer;
07.begin
08.for i := 1 to 2000 do ; begin
09.WriteLn('3T0 выполняется только один раз!');
10.end;
11.ReadLn;
12.end.
Delphi позволяет также создавать динамические многомерные массивы. Синтаксис объявления динамического многомерного массива выглядит следующим образом:
ИмяМассива: array of array of ТипДанных;
В следующем примере показано, как с помощью динамического многомерного массива можно создать представление шахматной доски. Все фигуры на доске занимают свои начальные позиции.
Листинг 6.8. Работа с динамическим многомерным массивом
01.program Project1;
02.{$APPTYPE CONSOLE}
03.uses
04.SysUtils;
05.var
06.ChessTable: array of array of Integer;
07.i: Integer;
08.j: Integer;
10.const
11.PAWN = 1;
12.ROOK = 2;
13.KNIGHT = 3;
14.BISHOP = 4;
15.QUEEN = 5;
16.KING = 6;
17.begin
18.{ allocate 8 empty arrays }
19.SetLength(ChessTable, 8);
20.for i := Low(ChessTable) to High(ChessTable) do
21.begin
22.{ define length of every array }
23.SetLength(ChessTable, 8);
24.for j := Low(ChessTable) to High(ChessTable) do
25.begin
26.{ set first line pieces }
27.if (i = 0) or (i = 7) then
28.case j of
29.0, 7: ChessTable[i, j] := ROOK;
30.1, 6: ChessTable[i, j] := KNIGHT;
31.2, 5: ChessTable[i, j] := BISHOP;
32.3: ChessTable[i, j] := QUEEN;
33.4: ChessTable[i, j] := KING;
34.end;
35.{ set pawn line }
36.if (i = 1) or (i = 6) then
37.ChessTable[i, j] := PAWN;
38.end; // for j
39.end; // for i
40.Finalize(ChessTable);
41.end.
Delphi автоматически управляет динамическими массивами. Память, зарезервированная под динамический массив, автоматически освобождается по завершении использования массива. Память массива можно освобождать также вручную, передавая имя массива процедуре Finalize. В данном случае процедура Finalize освобождает память, зарезервированную для массива ChessTable.
В функции и процедуры массивы можно передавать в качестве параметров, но нельзя указывать диапазон для параметра-массива. В следующем примере дается объявление процедуры, которое приводит к ошибке компиляции.
procedure WriteStrings(Str: array[1..20] of string);
begin
end;
Если процедуре нужно передать массив, состоящий из 20 строк, потребуется создать новый тип данных, а затем создать процедуру, которая принимает новый тип данных в качестве параметра. Для создания нового типа данных необходимо использовать зарезервированное слово type. Синтаксис создания нового типа данных показан ниже:
type
ТНовыйТипДаиных = СуществующийТип;
Чтобы создать новый тип данных, который представляет массив из 20 строк, необходимо написать такой код:
1.type
2.TSmallArray = array[1..20] of string; procedure WriteStrings(StrArray: TSmallArray);
var
3.item: string; begin
4.for item in StrArray do WriteLn(item);
5.end;
С этим решением связан один недостаток: процедура WriteString может принимать только переменную TSmallArray и, следовательно, мы ограничены массивом, состоящим из 20 строк. Если нужно работать с массивами других размеров, необходимо определить параметр типа открытого массива.
procedure ИмяПроцедуры{ИмяМассива: array of ТипДанных);
Параметры открытого массива позволяют передавать процедуре или функции массивы различных размеров. При этом можно передавать статические и динамические массивы и массивы нестандартных типов.
01.program Project1;
02.{$APPTYPE CONSOLE}
03.uses
04.SysUtils;
05.type
06.TSmallArray = array[1..20] of string;
07.var
08.SmallArray: TSmallArray;
09.DynamicArray: array of string;
10.StaticArray: array[1..100] of string;
11.procedure WriteStrings(StrArray: array of string);
12.var
13.item: string;
14.begin
15.for item in StrArray do
16.WriteLn(item);
17.end;
18.begin
19.WriteStrings(SmallArray);
20.WriteStrings(DynamicArray);
21.WriteStrings(StaticArray);
22.WriteStrings(['Open', 'Array', 'Constructor']);
23.ReadLn;
24.end.
Параметры открытого массива позволяют создавать массив непосредственно в вызове процедуры или функции. Этот процесс называют также передачей конструктора открытого массива. Конструктор открытого массива — это последовательность значений или выражений, заключенная в квадратные скобки и разделенная запятыми. Синтаксис использования конструктора открытого массива в вызове процедуры показан ниже:
Для создания массива строк внутри вызова процедуры WriteStrings можно использовать следующую строку кода:
WriteStrings(['Open1, 'Array', 'Constructor1]);
Параметры открытого массива могут оказаться весьма полезными при необходимости создания вспомогательной функции или процедуры, которая может работать с диапазоном значений. Например, если нужно создать функцию, вычисляющей среднее значение параметров, версия функции, которая может принимать массив значений, значительно более удобна, чем те. которые не могут это делать.
Листинг 6.10. Функция с параметром открытого массива