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;
Результат работы программы: