
如果将动态数组作为非var参数传递,则编译器将进行复制.
下面的小代码示例以表格形式显示37/42.

procedure IncArray1(data: array of integer);
var i : integer;
begin
for i := Low(data) to High(data) do
data[i] := data[i] + 5;
end;
procedure IncArray2(var data: array of integer);
var i : integer;
begin
for i := Low(data) to High(data) do
data[i] := data[i] + 5;
end;
procedure TForm8.FormCreate(Sender: TObject);
var
data: array of integer;
begin
SetLength(data,1);
data[0] := 37;
IncArray1(data);
Caption := IntToStr(data[0]);
IncArray2(data);
Caption := Caption + '/' + IntToStr(data[0]);
end;
如果我们成的汇编代码,IncArray1将启动

004552B4 8BCA mov ecx,edx 004552B6 85C9 test ecx,ecx 004552B8 7807 js $004552c1 004552BA 8B1C88 mov ebx,[eax+ecx*4] 004552BD 49 dec ecx 004552BE 53 push ebx 004552BF 79F9 jns $004552ba 004552C1 8B mov eax,esp
此代码将源数组复制到堆栈,并将eax设置为第一个元素的地址(=最后一次推送后存储在堆栈指针中的地址). 堆栈长度下降了,因此代码从最后一个元素开始(调用IncArray1时,edx包含高(数据))delphi数组间的赋值,然后重复执行(读取元素; push元素;减量索引)delphi数组间的赋值,直到到达元素0.

IncArray2不包含此类代码. 调用方在调用IncArray2之前将数据的地址存储在eax寄存器中,而IncArray2仅使用此地址.
如果出于任何原因不想使用“ var”,则可以将数据地址传递给您的方法. 但是,由于不能在参数声明中使用语法“ data: ^整数数组”,因此必须在data中声明类型. 在该方法中,必须使用'data ^'而不是'data'.

type
TData = array of integer;
PData = ^TData;
procedure IncArray(data: PData);
var i : integer;
begin
for i := Low(data^) to High(data^) do
data^[i] := data^[i] + 5;
end;
procedure TForm8.FormCreate(Sender: TObject);
var
data: TData;
begin
SetLength(data,2);
data[0] := 37;
IncArray(@data);
Caption := IntToStr(data[0]);
end;
在Delphi 2007中进行了测试.
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-274204-1.html
千万别升
#杨洋icon##杨洋2015金投赏#杨洋金投赏