オープン配列パラメータとは、異なるサイズの配列を同じ手続き、又は関数に渡せることを言います オープン配列パラメータの宣言は以下のようになります。
procedure MyProc(Arr: array of Integer); begin .......... end;
このように、パラメータに array of 型 としてやることでオープン配列パラメータにすることが出来ます。早速、例を見てみましょう。フォームには ListBox が2つ、Button が1つ貼り付けてあります。
procedure MyProc(Arr: array of Integer);
var
i: Integer;
begin
for i := Low(Arr) to High(Arr) do
begin
Arr[i] := 10; // 受け取った要素を全て10にする
Form1.ListBox2.Items.Add('Array[ ' + IntToStr(i) + ' ] = ' +
IntToStr(Arr[i]));
end;
Form1.ListBox2.Items.Add('');
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
Arr1: array[0..3] of Integer;
Arr2: array[0..5] of Integer;
begin
for i := Low(Arr1) to High(Arr1) do
begin
Arr1[i] := i;
ListBox1.Items.Add('Arr1[ ' + IntToStr(i) + ' ] = ' +
IntToStr(Arr1[i]));
end;
ListBox1.Items.Add(''); // 一行間隔をあけます
for i := Low(Arr2) to High(Arr2) do
begin
Arr2[i] := 100 + i;
ListBox1.Items.Add('Arr2[ ' + IntToStr(i) + ' ] = ' +
IntToStr(Arr2[i]));
end;
// 手続きMyProcに、それぞれの配列を渡す
MyProc(Arr1);
MyProc(Arr2);
end;
ここでは、受け取った配列の要素を全て10に変更しています。このように、サイズの異なる配列を1つの手続きに渡すことが出来ます。また、配列のサイズを知る為に Low()、High() を使用している点にも注目してください。ただ、オープン配列パラメータの場合、添え字は常に0から始まるという規則がありますので、その点は注意が必要です。
また Slice 関数を使うことによって、渡す配列の要素数を予め決めることが出来ます。
procedure MyProc(Arr: array of Integer);
var
i: Integer;
begin
for i := Low(Arr) to High(Arr) do
begin
Arr[i] := 10;
Form1.ListBox2.Items.Add('Array[ ' + IntToStr(i) + ' ] = ' +
IntToStr(Arr[i]));
end;
Form1.ListBox2.Items.Add('');
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
Arr1: array[0..3] of Integer;
Arr2: array[0..5] of Integer;
begin
for i := Low(Arr1) to High(Arr1) do
begin
Arr1[i] := i;
ListBox1.Items.Add('Arr1[ ' + IntToStr(i) + ' ] = ' +
IntToStr(Arr1[i]));
end;
ListBox1.Items.Add('');
for i := Low(Arr2) to High(Arr2) do
begin
Arr2[i] := 100 + i;
ListBox1.items.Add('Arr2[ ' + IntToStr(i) + ' ] = ' +
IntToStr(Arr2[i]));
end;
MyProc(Arr1);
MyProc(Slice(Arr2, 3)); // (1)
end;
(1)のように Slice 関数を使用した場合、Arr2 は配列の先頭から、つまり Arr2[0] から Arr2[1]、Arr2[2] の3つが手続き MyProc に渡されることになります。それでは、もう一つ例を見てみましょう。
function Sum(A: array of Integer): Integer;
var
i: Integer;
begin
Result := 0;
for i := Low(A) to High(A) do
Inc(Result, A[i]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Arr: array[0..5] of Integer;
i: Integer;
begin
Arr[0] := 1;
Arr[1] := 2;
Arr[2] := 3;
Arr[3] := 4;
Arr[4] := 5;
Arr[5] := 6;
i := Sum(Arr);
ShowMessage('合計 ' + IntToStr(i));
end;
オープン配列パラメータは動的配列の宣言と似ていますが、動的配列の宣言ではないので注意してください。つまりパラメータ(引数)で「array of ..」となっていたら、必ずオープン配列パラメータです これは、動的配列を渡せないということでは、ありません。以下のように動的配列も渡せます。
function Sum(A1, A2: array of Integer): Integer;
var
i, x1, x2: Integer;
begin
x1 := 0;
x2 := 0;
for i := Low(A1) to High(A1) do
Inc(x1, A1[i]);
for i := Low(A2) to High(A2) do
Inc(x2, A2[i]);
Result := x1 + x2;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Arr1: array[0..5] of Integer;
Arr2: array of Integer;
i: Integer;
begin
Arr1[0] := 1;
Arr1[1] := 2;
Arr1[2] := 3;
Arr1[3] := 4;
Arr1[4] := 5;
Arr1[5] := 6;
SetLength(Arr2, 3);
Arr2[0] := 1;
Arr2[1] := 10;
Arr2[2] := 100;
i := Sum(Arr1, Arr2);
ShowMessage('合計 ' + IntToStr(i));
end;
では、何が出来ないのかというと渡された動的配列のサイズの変更が出来ないのです。
function Sum(Arr: array of Integer): Integer;
var
i: Integer;
begin
Result := 0;
for i := Low(Arr) to High(Arr) do
Result := Result + Arr[i];
i := SizeOf(Arr) div SizeOf(Integer);
ShowMessage('要素数は ' + IntToStr(i));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
// 直接配列を作成
i := Sum([10, 20, 20, 30]);
ShowMessage('合計 ' + IntToStr(i));
i := Sum([1, 2, 3]);
ShowMessage('合計 ' + IntToStr(i));
end;
このように、手続き又は関数の呼び出し時に直接配列を作成して渡すことが出来ます。
関数や手続きのパラメータに動的配列を宣言する方法は別にあります。その場合は、新しい型を自分で宣言してから使わなければなりません。下の例を参考にして下さい。
type
// 独自の型を定義
TDynamicArr = array of Integer;
..................................
procedure Sum(var A: TDynamicArr);
begin
SetLength(A, 20);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Arr: TDynamicArr;
i: Integer;
begin
SetLength(Arr, 10);
i := Length(Arr);
ShowMessage('要素数は ' + IntToStr(i));
Sum(Arr);
i := Length(Arr);
ShowMessage('要素数は ' + IntToStr(i));
end;
このようにした場合、サイズの変更が可能になります。