Site icon Обучение программированию с нуля

Передать вариантный массив в функцию

Delphi 7. Занятие 2_6. Часть 4.

Рассматриваемые задачи.

Передать динамический массив в функцию

Ранее мы рассмотрели создание как одномерного , так и многомерных динамических массивов (ссылка https://programlife.ru/delphi/delphi-dinamicheskij-massiv).

Рассмотрим, как передать динамический массив в функцию через вариант-параметр. Отметим, что передавать можно только одноразмерный динамический массив!

Создадим функцию:

function fVar1(v:variant; n:integer):variant;//через «n» передаём мощность (количество элементов) массива.

var s:string; j:integer;

begin

s:=»;

for j:=0 to n-1 do //пробегаем все элементы массива

begin

s:=s+’ ‘+varToStr(v[j]); //создаём строку, преобразуя вариантное значение в строку с помощью функции varToStr.

end;

result:=s; //функция вернёт значение типа «вариант», содержащее строку «s» (так как функция объявлена как возвращающая тип «variant»,

end;

Процедура, вызывающая функцию:

procedure TForm1.Button2Click(Sender: TObject);

type tvDinArr=array of integer; //объявляем динамический массив

var vDinArr:tvDinArr; v:variant; n:integer;

begin

n:=3;

setLength(vDinArr,n); //устанавливаем размерность динамического массива (распределяем память)

vDinArr[0]:=11; vDinArr[1]:=22; vDinArr[2]:=33; //вводим значения

v:=fVar1(vDinArr,n); //вызываем функцию и передаём в неё динамический массив. Результат записываем в вариантную переменную.

edit13.Text:=varToStr(v); //преобразуем вариантное значение в строковое.

End;

Результат работы программы:

delphi variant

В предыдущем разделе мы рассмотрели, как динамические массивы данных передаются в качестве параметров в процедуру или функцию.

Теперь покажем, как создать вариантный массив и передать его в процедуру.

Вариантный массив

В отличие от динамического массива, передаваемого в процедуру, вариантные массивы могут быть многомерными. Кроме того, отдельные ветви массива могут быть сами вариантными массивами.

Передача в процедуру вариантного массива

Рассмотрим это на примере.

В функции fVar3 осуществляем следующие шаги.

//1 с помощью функции varArrayDimCount() определяем размерность m передаваемого в функцию вариантного массива v.

//2 инициируем первую размерность вспомогательного динамического массива с размерностью, равной m: setLength(DAr,m).

//3 создаём цикл, который выполнится столько раз, сколько размерностей m содержит вариантный массив v.

//4 инициируем вторую размерность вспомогательного динамического массива setLength(DAr[ii],2). Нижний индекс динамического массива по любому измерению всегда равен «0». Поэтому ii должно изменяться от 0 до m-1. В примере рассмотрен трёхмерный динамический массив, поэтому первый индекс может принимать значения 0, 1 и 2.

//5 с помощью функции varArrayLowBound(v,ii+1) определяем наименьшее значение индекса вариантного массива по измерению номер ii+1. Помним, что отсчет измерений начинается с 1, а индексов в динамическом массиве с 0. Сохраняем значение индекса в ячейке динамического массива DAr[ii,0]. В нашем примере использован трехмерный вариантный массив. Наименьшие значения индекса по соответствующим измерениям равны 1,0 и 3.

//6 аналогично сохраняем в динамическом массиве высший индекс по измерению, равному ii+1: DAr[ii,1]:=varArrayHighBound(v,ii+1);

//7 значение, хранящееся в конкретной ячейке выриантного массива, может быть прочитано в зависимости от того, какова размерность передаваемого в функцию вариантного массива. В зависимости от значения этой размерности осуществляется выбор в операторе case. Будем считать, что на практике мы вряд ли будем использовать массив с размерностью, большей пяти. Но поняв принцип, можно расширить приведённый алгоритм.

// для чтения значения из конкретной ячейки в функцию передаются значения индексов этой ячейки. Значения индексов передаются с помощью дополнительного вариантного массива w.

Таким образом, функция формирует строку, в которой содержится информация о границах индексов по каждой размарности вариантного массива.

Результат возвращается в вызывающую процедуру такжк в виде варианта (функция возвращает значение типа «variant»).

function fVar3(v,w:variant):variant;

var i,j,k,l,n,ii,m,nn,nl,nh:integer; vv,v1,v2,v3:variant;

DAr:array of array of integer;

ss:string;

begin

ss:=»;//обнуляем строку

//исследуем вариантный массив

m:=varArrayDimCount(v); //1 Размерность массива

setLength(DAr,m); //2 Вспоминаем, как инициируется динамический массив делфи. Сначала инициируем вспомогательный динамический массив по первому индексу.

for ii:=0 to m-1 do //3 определяем низший и высший индекс по каждому измерению

begin

setLength(DAr[ii],2); //4 инициируем вторую размерность вспомогательного динамического массива.

DAr[ii,0]:=varArrayLowBound(v,ii+1); //5 сохраняем в динамическом массиве низший индекс по измерению, равному ii+1

DAr[ii,1]:=varArrayHighBound(v,ii+1); //6 сохраняем в динамическом массиве высший индекс по измерению, равному ii+1

end; //for

case m of //7 опреатор выбора

1:begin i:=w[0]; //если передаваемый в функцию массив одномерный

vv:=v[i]; end;

2:begin i:=w[0]; j:=w[1];//если передаваемый в функцию массив двумерный

vv:=v[i,j]; end;

3:begin i:=w[0]; j:=w[1]; k:=w[2];//если передаваемый в функцию массив трёхмерный

vv:=v[i,j,k]; end;

4:begin i:=w[0]; j:=w[1]; k:=w[2]; l:=w[3];//если передаваемый в функцию массив четырёхмерный

vv:=v[i,j,k,l]; end;

5:begin i:=w[0]; j:=w[1]; k:=w[2]; l:=w[3]; n:=w[4];//если передаваемый в функцию массив пятимерный

vv:=v[i,j,k,l,n]; end;

end;//case

for ii:=0 to m-1 do //формируем строку, содержащую информацию об индексах вариантного массива. Она может быть полезной в конкретных ситуациях.

begin

ss:=ss+’ низший индекс по измерению ‘+intToStr(ii+1)+’ равен ‘+intToStr(DAr[ii,0])+

‘; вызший индекс по измерению’+intToStr(ii+1)+’ равен ‘+intToStr(DAr[ii,1])+’#’;

end;

result:=’размерность массива=’+inttostr(m)+’#’+ss+’%’; //символы «# и %» понадобится при разборе строки для её вывода в компонент memo.

end;

В обработчике клика по кнопке создаётся трехмерный вариантный массив v, а также вспомогательный одномерный вариантный массив vw.

Вызываемая функция возвращает строку. Используя стандартные функции для работы со строками, формируем значения для компонента memo.

procedure TForm1.Button5Click(Sender: TObject);

var v,vv,vw:variant; s,ss:string; len,ps,i,j,k,l,n,ln:integer;

begin

s:=»;

v:=varArrayCreate([1,2,0,1,3,4],varVariant); //создаём трёхмерный вариантный массив. Индексы первого измерения от 1 до 2; второго измерения от 0 до 1; третье измерение — от 3 до 4.

v[1,0,3]:=103; v[2,0,3]:=203;

i:=1;j:=0;k:=3;l:=0;n:=0;

vw:=varArrayOf([i,j,k,l,n]);//создаём одномерный (функция varArrayOf может создавать только одномерный вариантный массив). Создаём массив из пяти компонентов.

vv:= fVar3(v,vw);//вызываем функцию fVar3. Функция возвращает значение типа «вариант».

s:=varToStr(vv);//преобразуем значение из варианта в переменную типа «строка».

ln:=Length(s);//с помощью строковой функции Length определяем длину (количество символов) строки.

repeat //цикл. В цикле уменьшаем длину строки до тех пор, пока она не станет меньше 3-х символов.

ps:=Pos(‘#’,s);//с помощью строковой функции «Pos» определяем позицию первого расположения символа «#» в строке.

ss:=copy(s,1,ps-1);//с помощью строковой функции copy копируем часть строки, начиная с 1-ой позиции вплоть до симола с позицией ps-1.

s:=copy(s,ps+1,ln);// «затираем» старое содержимое строки s и помещаем туда часть строки, начиная с позиции «ps» и до конца строки (позиция «ln»).

ln:=Length(s); //определяем новую длину строки «s».

form1.Memo1.Lines.Add(ss) //записываем в Memo1 строку «ss»

until ln<3; //если длина строки стала меньше 3-х символов, прекращаем цикл.

end;

Результат работы программы: