当过程或函数使用数组参数时,不能在声明参数时包含索引说明符。也就是说,声明定义下面函数将产生编译错误。
procedure Sort(A:array[1..10] of Integer);//语法错误
但使用下面这种方法是有效的。但在大多数情况下,开放数组参数是更好的办法。
type TDigits=array[1..10]of Integer; procedure Sort(A:TDigits);
开放数组参数允许传递不同长度的数组到一个过程或函数。要定义一个使用开放数组参数的方法,在声明参数时使用“array of type”。
function Find(A: array of Char):Integer;
虽然定义开放数组参数的语法和定义动态数组相似,但它们的意义不同。上面的例子创建了一个函数,它可以接收由字符构成的任何数组,包括静态和动态数组。对于仅接收动态数组的参数,你需要指定一个类型标识符:
type TDynamicCharArray = array of Char; function Find(A:TDynamicCharArray): Integer;
开放数组参数遵循以下规则:【注1】
(1)数组元素的下标总是从0开始,第一个是0,第二个是1,依此类推。
不论实参(实际数组)下标从什么开始,Low(arr)返回0,High(arr)返回Length-1。
//测试代码procedure ListAllIntegers(const arr: array of Integer); var I: Integer; begin for I := Low(arr) to High(arr) do WriteLn(arr[I], '的索引是', I); end; //测试数据 var arr: array[7..9] of Integer; begin arr[7] := 7; arr[8] := 8; arr[9] := 9; ListAllIntegers(arr); end.
结果:
(2)只能访问数组中的元素。对整个开放数组参数(即形参变量)赋值是不允许的。因为开放数组可能传递的是静态数组,而静态数组不能重新分配内存。
(3)可以将开放数组参数传递给其他同类型的开放数组形参或无类型参数(untyped parameters【注2】)。
They can be passed to other procedures and functions only as open array parameters or untyped var parameters. They can not be passed toSetLength.
//无类型参数 procedure func1(var arr); begin WriteLn(Integer(arr)); end; //开放数组参数 procedure func2(arr:array of Integer); begin WriteLn(arr[0]); end; //测试调用该函数 procedure func3(arr:array of Integer); begin WriteLn('无类型参数调用结果:'); func1(arr); WriteLn('开放数组参数调用结果:'); func2(arr); end;
结果:
(4)可以将一个变量传递给相同类型的开放数组,它将自动被当成长度为1的数组。
(5)当把一个数组作为开放数组的值参数传递时,编译器将在栈中创建数组副本。因此在传递大的数组时小心栈溢出,尽量使用const或var修饰开放数组参数。
注1:请参见http://www.87871.cn/tool/help/Pascal/Source/Procedures%20and%20functions/Open%20array%20parameters.htm
注2:关于无类型参数请参见http://www.87871.cn/tool/help/Pascal/Source/Procedures%20and%20functions/Untyped%20parameters.htm