
- •Лекция 6. Массивы (продолжение).
- •Расширение понятия «массив».
- •Начальные сведения об указателях
- •Простой пример
- •Связь массивов и указателей.
- •Пример использование указателей вместо операции индексации
- •Двумерные массивы – матрицы.
- •Допускается указание диапазонов по строкам и столбцам разного типа. Например, матрица из двух
- •BEGIN
- •Динамические массивы.
- •Недостатками динамических массивов является строгое равенство нулю индекса первого элемента, т.е. отсчет всегда
- •Синтаксис объявления двумерного массива динамического массива (матрицы)
- •Гораздо сложнее обстоит дело с многомерными массивами, в частности с матрицами, поскольку линейная
- •BEGIN
- •Анализ этих результатов позволяет сделать следующие выводы:
- •Одномерные динамические массивы, напомню, фактически это указатели могут быть переданы в подпрограмму следующим
Лекция 6. Массивы (продолжение).
Или еще кое что о массивах.
1.Расширение понятия «массив»
2.Начальные сведения об указателях и их связь с массивами.
3.Двумерные массивы – матрицы.
4.Динамические массивы.
Расширение понятия «массив».
Казалось бы, чего тут чудить-мудрить, и так все ясно, массив - это совокупность однотипных элементов с одинаковым именем, но снабженные уникальным индексом.
Правда это только с точки зрения человека, который «с точки зрения компьютера», ну той самой матрицы (кино такое),
вроде как бы и не существует. Иначе говоря, если чего то сложно устроено, то это надо, как то себе, (человеку) объяснить.
Попробуем. Одномерные массивы и линейная память компьютера идеально соответствуют друг другу. Правда и
здесь есть некоторые проблемы, связанные с тем, что мы
не знаем, как массив представлен в оперативной памяти компьютера, точнее нам это не интересно. А что
уж говорить про двумерные массивы – матрицы, ведь память то, как была линейная, так и осталась.
Ивот для того, чтобы выяснить это, рассмотрим, вначале, понятие нового типа - указателя.
Начальные сведения об указателях
По простому – указатель это адрес той самой переменной, на которую он указывает. Если указатель содержит в себе еще и сведения о типе, вроде BYTE, CHAR, INTEGER или
REAL, то такие указатели называются типизированными. Они «знают», как скроена та переменная, адресом которой они является. Если указатель просто указывает на некоторый адрес, то он является указателем без типа или просто адресом.
Итак, указатели - это адреса, которые где то надо хранить. На большинстве компьютеров на сегодняшний день (не ручаюсь на завтра) используются 4-х байтовые адреса, которые вполне могут быть преобразованы к типу LONGWORD или INTEGER хотя бы для того, чтобы на них можно было посмотреть, но и не только для этого.
Иначе говоря адресное пространство таких компьютеров составляет 24*8 = 232 = 4294967296 -1 байт (отсчет от нуля).

Простой пример
Var c : char; |
// |
Это переменная |
pc : ^char; // |
А это указатель на нее |
|
BEGIN |
|
|
c:='z'; |
// |
Присвоили ей значение |
pc:=@c; |
// |
Присвоили указателю адрес |
writeln(c); |
// |
Понятно – это z |
writeln(pc^); // |
Разыменованное значение тоже z |
writeln(longword(pc)); // А это сам указатель readln;
End.

Связь массивов и указателей.
Для начала этих знаний достаточно, и можно перейти к массивам
Const n=11;
Type Ta=array[1..n] of integer; Var a : Ta;
pa : ^integer;
BEGIN
pa:=addr(a); //Функция получения адреса – это writeln(integer(pa));// то же самое, что и pa:=@(a[1]); //операция получения адреса writeln(integer(pa));
readln;
End.

Пример использование указателей вместо операции индексации
Var a |
: Ta; pa : ^integer; i : integer; |
|
BEGIN |
|
|
for |
i:=1 to n do a[i]:=i; |
|
for |
i:=1 to n do |
write(a[i]:3); writeln; |
for |
i:=1 to n do |
write(GetA(a,i):3); writeln; |
readln;
End.
Двумерные массивы – матрицы.
Двумерные массивы или матрицы имеют два индекса, первый из которых обычно отождествляется с номером строки, а второй – с номером столбца. Число строк и число столбцов составляют размерность матрицы. Как правило, размерности числовых матриц задается константами.
Примеры.
Стандартные числовые матрицы – первый индекс равен 1.
Const m=3; n=4;
Type TByteArr=array[1..m,1..n] of byte; TRealArr=array[1..m,1..n] of real;
Не стандартные числовые матрицы.
Type TByteArr=array[-m..m,-n..n] of byte; TRealArr=array[0..m,0..n] of real;
Допускается указание диапазонов по строкам и столбцам разного типа. Например, матрица из двух строк (от false до
true) и 26 столбцов может быть следующей
Type TWordArr=array[boolean, 'a'..'z'] of word;
Впамяти компьютера матрицы хранятся по срокам. Убедиться
вэтом можно с помощью функции GetA.
Пример.
Const m=3; n=4;
Type Ta=array[1..m, 1..n] of integer;
{ Здесь надо разместить текст функции GetA из предыдущего примера}
Var a : Ta;
i, j, k : integer;

BEGIN
//Формирование матрицы значениями, равными
//индексам
for i:=1 to m do
for j:=1 to n do a[i, j]:=i*10+j;
//Вывод в виде таблицы for i:=1 to m do begin
for j:=1 to n do write(a[i, j]:3); writeln; end;
writeln;
//Вывод фрагмента памяти одной строкой
for k:=1 to m*n do write(GetA(a, k):3); writeln;
readln;
End.
Динамические массивы.
До сих пор все рассматриваемые примеры относились к статическим массивам, память под которые выделялась на этапе компиляции программы и на этапе выполнения уже не могла быть изменена. Можно сказать и так, что это цена, которую надо платить за гибкое управление индексами и быстродействие.
Наряду со статическими массивами в DELPHI имеются динамические массивы, которые позволяют менять свой
размер во время исполнения программы. Их целесообразно использовать, если размерность массива заранее не известна и может меняться в очень широких пределах. В этой ситуации применение статических массивов требует больших затрат памяти, которую пришлось бы выделять по максимуму.