Открытые параметры-массивы процедур
Недостаток рассмотренных процедур обработки массивов в том, что их можно использовать только с массивами типа T_Mxy, у которого количество элементов задано и не может быть изменено. Для обработки массива другого типа, отличающихся количеством элементов, либо нумерацией индексов, надо создавать другую процедуру.
Особенностью открытых параметров-массивов в процедурах является отсутствие указания на размерность массива в заголовке, что обеспечивает процедурам возможность работать с массивами различной размерности.
procedure Имя_Проц(Имя_Массива: array of базовый тип)
procedure Open_Vec(Vector: array ofReal)
//Индексы массива в заголовке не указаны.
При работе с открытыми параметрами следует учитывать:
· открытый параметр-массив может быть как параметром-значением так и параметром-переменной;
· фактический параметр должен совпадать по типу с указанным в описании базовым типом, а размерность может иметь любую;
· все формальные открытые параметры-массивы интерпретируются как массивы с нулевой базой.
Для определения характеристик переданного фактического параметра-массива в теле процедуры используют следующие стандартные функции:
Low(Vec) – возвращает младшее значение индекса массива, для открытых параметров-массивов – всегда 0.
High(Vec) – для открытого параметра-массива возвращает значение типа Word, показывая число элементов в фактическом параметре, минус 1. Для обычных массивов – старшее значение индекса массива.
Пример 3. Открытые параметры
Объявим в процедурах формирования массива (пример 2) Cr_Mx и Cr_My параметры-массивы открытыми. Изменения, в сравнении с предыдущими вариантами, выделены курсивом. Все остальные процедуры – без изменения, и здесь не приведены.
procedure Cr_Mx(Str_X, Str_d : string; Var MM: array of Real);
{Процедура формирует массив ММ. ММ - открытый параметр-переменная. Str_X - строка соответствующая Х0. Str_d - строка соответствующая dX.}
var i: Byte; //счётчик
dX: Real; //приращение dХ
Begin
MM[0] :=StrToFloat(Str_X); {Преобразование строки Str_X в элемент
MM[0] массива МM. Счёт от 0}
dX := StrToFloat(Str_d); //преобразование строки Str_d в число dX
for i :=1 To High(MM) do//High(MM) – старший индекс
MM[i]:= MM[i-1]+dX; //цикл формирования массива
End;
procedure Cr_My(Mx: array of Real; var My: array of Real; n: real );
{Формирует массив My по значениям функции FXn(Mx[i], n). Мy - открытый параметр-переменная. n – показатель степени.}
var i: byte; //счётчик
Begin
for i:= 0 to High(Mx) do//счёт от 0 до старшего индекса
My[i]:= FXn(Mx[i], n);
End;
Рассмотренные процедуры позволяют обрабатывать массивы с различным количеством элементов.
Начало |
Схема алгоритма. Формирование массива Mx procedure Cr_Mx(Str_X, Str_d : string; Var MM: array of Real) |
Преобразование Строка-Число MM[0] :=StrToFloat(Str_X) dX := StrToFloat(Str_d); |
MM[i]:= MM[i-1]+dX |
Цикл по i, 1..High(MM) |
Конец |
True |
Начало |
My[i]:= FXn(Mx[i], n) Функция FXn возводит Mx[i] в степень n |
Цикл по I, 1..m m – количество элементов |
Конец |
True |
Схема алгоритма. Формирование массива My по значениям Mx procedure Cr_My(Mx: T_Mxy; var My: T_Mxy; n: real ) |
Динамические массивы
Недостаток открытых параметров-массивов в том, что количество элементов массива является константой и определено в тексте программы до её выполнения, а константу в процессе выполнения программы изменять нельзя. Динамические массивы позволяют задать массив, у которого количество элементов задаётся переменной. При объявлении таких массивов границы индексов не указывают:
Var
A:array of Integer; //одномерный динамический массив
Динамические массивы не имеют установленного размера или длины. Распределение памяти и указание границ индексов по каждому измерению динамических массивов осуществляется в ходе выполнения программы путем инициации массива процедурой SetLength.
SetLength(var S; NewLength: Integer) - устанавливает длину переменной динамического массива,
где S - переменная - динамический массив;
NewLength - число элементов массива, нижняя граница индексов
динамического массива всегда равна 0.
Фактически идентификатор динамического массива ссылается на указатель, содержащий адрес первого байта памяти, выделенной для размещения массива (динамические переменные будут рассмотрены позднее). Для освобождения памяти занятой массивом достаточно присвоить идентификатору значение nil или использовать процедуру Finalize.
Var
А, В:array of Integer;
………………….
begin// определяем размеры массивов
SetLength(A,10) ; //10 элементов типа Integer
SetLength(B,20) ; //20 элементов
// Используем массивы:
А := nil; //освобождаем память
Finalize(В); //освобождаем память
………………….