Procedure SORT . . .

. . .

. . .

. . .

. . .

Передача массивов в качестве параметров в подпрограммы. Открытые массивы

Подпрограммы (процедуры и функции) зачастую в качестве входных параметров должны обрабатывать массивы данных.

В простейшем случае размерность обрабатываемых массивов постоянна, их можно описать в вызывающем блоке как отдельный тип данных, в котором указан как тип элементов, так и их число. Этот тип данных должен быть использован в заголовке подпрограммы. Перед ее вызовом во внешнем блоке программы должен быть сформирован статический массив данного типа, который передается в подпрограмму в качестве формального параметра. Такое способ назовем передачей с объявлением (описанием) типа массива в вызывающем блоке.

Пример 1. В процедуру сортировки SORT необходимо передавать целочисленные массивы длины 10. Для этого вначале в вызывающем блоке описывают соответствующий тип int_ar_10, который затем используем в заголовке процедуры:

type int_ar_10 = array [1..10] of integer;

procedure SORT(ent_mas:int_ar_10; var exit_mas:int_ar_10);

Рассмотренная конструкция проста, однако процедуру SORT можно использовать только для сортировки целочисленных массивов длины 10.

Если необходимо упорядочивать массивы различной длины, например, содержащих от 1 до 100 элементов, простейший выход заключается в описании типа int_ar_100с числом элементов (100) и дополнительной передаче в процедуру еще одного параметра, задающего действительную длину обрабатываемого массива. Данный способ относительно прост, однако он подразумевает наложение ограничения на длину массива (для 101 элемента процедура уже не подходит). Также при обработке коротких массивов нерационально будет использоваться память из-за того, что в соответствующих переменных типа int_ar_100будет использоваться только малая часть элементов.

Требование объявления типа массива в разделе описания typeтакже нарушает требование переносимости подпрограмм, поскольку их корректная работа в этом случае зависит от обязательного выполнения некоторых дополнительных внешних действий.

Для устранения перечисленных недостатков при передаче статических массивов в подпрограммы необходимо использовать открытые массивы, которые, как и динамические, непосредственно применяют только для одномерного случая.

Применение открытых одномерных массивов для передачи в подпрограмму статических массивов заключается в следующем. В заголовке подпрограммы массив описывается, подобно динамическому, без указания его размера, задается только тип элементов. Однако при вызове подпрограммы подставляемые в нее фактические параметры - массивы должны быть объявлены в разделе описания переменных var вызывающего блока как обычные статические массивы - с указанием и типа элементов и их числа.

Применение открытых массивов не предусматривает передачи длины массива-параметра в подпрограмму в качестве ее отдельного параметра (как при использовании статических массивов избыточной длины). Для отслеживания границ одномерного массива-параметра внутри подпрограммы необходимо использовать стандартные функции Low и High. Их единственным параметром является идентификатор массива, Low возвращает начальное значение его индекса, а High -- конечное. Обычно динамический массив начинается с элемента с номером 0, однако надежнее применять функцию Low.

Пример 2. Рассмотрим использование процедуры сортировки SORT с использованием открытых массивов для обработки целочисленных массивов произвольной длины, которая задается в вызывающем блоке. Для этого: 1) входнойent_mas и выходнойexit_mas массивы процедурыSORT описаны как открытые, без указания длины, 2) для отслеживания границ массивов ent_mas и exit_mas в теле SORT использованы переменные i_first, i_fin(ent_mas) и j_first, j_fin(exit _mas), в которые номер начального и конечного элементов массивов засылаются при помощи функций Low и High, 3) поскольку длины входного и выходного массивов должны быть одинаковы, то дополнительно выполняется проверка (i_fin-i_first) <> (j_fin - j_first). Схема программного кода с комментариями имеет вид:

var a,b:array [1..8] of integer;{описание во внешней программе статических массивов a,b}

procedure SORT(ent_mas: array of integer; var exit_mas: array of integer);

var i_first,i_fin,j_first,j_fin:integer;{описание в SORT переменных для границ массивов}

begin{начало тела процедуры SORT}

i_first:=Low(ent_mas);i_fin:=High(ent_mas);{определение границ массиваent_mas}

j_first:=Low(exit_mas);j_fin:=High(exit_mas);{определение границ массива exit_mas}

if (i_fin-i_first)<>(j_fin-j_first) then begin

wirteln (’ Different lengths of arrays in proc. SORT, EXIT!’); exit end;

end;{конец тела процедуры SORT}

begin{начало тела внешней программы}

SORT(a,b); {вызов процедуры SORT с подстановкой в нее статических массивов a,b }

end. {конец тела внешней программы}

В приведенном примере процедура SORT может быть использована для упорядочения массивов любой длины, которая задается в вызывающем блоке. Однако зачастую длина входного массива заранее не известна и в вызывающем блоке – обычно она определяется в результате расчетов или задается пользователем. Поэтому для передачи такого набора данных необходимо вместо статического использовать динамический тип массивов.

Пример 3. Рассмотрим решение задачи из примера 2 для случая, когда размерность входного линейного массива заранее неизвестна и во входном блоке. Она должна вводиться с клавиатуры, после чего также вводятся величины элементов массива. Поскольку в подпрограмме SORT все сохраняется, рассмотрим только код вызывающего блока:

var a,b:array of integer;{описание во внешней программе динамических массивов a,b}

n:integer;

begin{начало тела внешней программы}

writeln ('Vvedite razmernost massiva:');read(n);{запрос и ввод размерности n}

SetLength (a,n); SetLength (b,n);{Задание длины nдинамическим массивамaи b}

for i:=1 to n do begin {ввод элементов массиваa с клавиатуры}

writeln('vvedite element a[',i,']=');{запрос на ввод элемента a[i]}

read(a[i]){ввод элемента a[i] в линейный динамическиймассив a }

end;. . .

SORT(a,b); {вызов процедуры SORT с подстановкой в нее динамических массивов a,b }