Представим, что перед программистом поставлена задача разработки программного модуля для хранения фамилий студентов или что-нибудь похожее, связанное с обработкой большого количества однотипных данных. Использование обычных переменных для хранения упорядоченных наборов данных одного типа не является эффективным решением подобных задач. Явное неудобство состоит в объявлении десятков, сотен или даже тысяч переменных, а сложность обращения к каждой из них тем более не нуждается в доказательствах. Выходом из такой ситуации является применение массивов (array).
Массив, как и переменную, необходимо объявить. Для этого нужно указать размерность массива и тип хранимых данных:
var <имя_массива>: array [<нижняя граница> <верхняя граница>] of <тип_элементов>;
Если в программе будут применяться несколько однотипных массивов, то предварительно стоит определить тип массива, а затем создавать массивы на базе объявленного типа:
type TMyArray = Array [0..9] of integer; // массив из 10 элементов var Array1, Array2 : TMyArray;
Для обращения к элементам массива с целью чтения или записи достаточно указать индекс элемента в массиве:
NewArray[0]:=199; // 0-му элементу массива присваивается значение 199 I:=NewArray[9]; // в переменную I записано содержимое 9-го элемента массива
ОПри обращении к элементам массива внимательно следите за тем, чтобы передаваемый индекс не выходил за границы массива, в противном случае вы получите сообщение об ошибке.
Иногда полезно задавать массив в виде константы. В следующем примере 12 ячеек массива используются для хранения количества дней в месяцах високосного года:
const
DaysInMonth: array [1..12] of byte = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
ОХотя Delphi допускает задание нижней границы массива любым числом (например, массив DaysInMonth), но хорошей практикой считается начинать нумерацию с нуля. Кстати, методы Low() и High(), возвращающие границы массива, предназначены для работы только с массивами, начинающимися с нуля, иначе они вернут ошибочные значения.
Вполне реально объявлять «квадратные» и «кубические» массивы, а также массивы более высоких размерностей. Например, объявление двумерного массива размерностью 10 на 10 ячеек выглядит следующим образом:
var MyArray : Array[0..9,0..9] of cardinal;
или
var MyArray : Array[0..9] of Array[0..9] of cardinal;
Но теперь, для того чтобы обратиться к интересующей нас ячейке двумерного массива, потребуется указать 2 индекса:
MyArray[3,6]:=56; или
MyArray[3][6]:=56;
Чем больше элементов включает массив, тем значительнее затраты памяти на хранение его содержимого. Например, двумерный массив типа DWord размерностью всего 100 на 100 элементов потребует 100 х100 х 8 байт = 80 000 байт оперативной памяти. Но зачастую размерность массива определяется с запасом (на всякий случай), а в ходе выполнения программы последний не заполняется и на 50%. Жаль потерянные байты. В таких случаях применяйте сжатые (packed) массивы:
var MyArray : packed array [0..99,0..99] of cardinal;
Такой способ объявления гарантирует более рачительное использование ОЗУ, но несколько снижает скорость доступа к элементам массива.
У рассмотренного выше способа хранения данных есть один существенный недостаток - объявив размерность массива (сделав его статическим), мы не сможем выйти за его границы. А что делать, если заранее даже приблизительно неизвестно, сколько элементов может оказаться в массиве? В таких случаях используют динамические массивы, которые отличаются от статических тем, что их границы могут изменяться во время работы приложения.
Естественно, объявление динамического массива выглядит несколько иначе:
var MyArray: array of INTEGER;
Как видите, при объявлении массива мы не определяем его размерность. Но перед заполнением массива нам все-таки придется это сделать с помощью метода SetLength():
SetLength(MyArray, 10); //распределяем память для 10 элементов массива