在Delphi中如何通过引用传递数组? [英] How do you pass an array by reference in Delphi?

查看:173
本文介绍了在Delphi中如何通过引用传递数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了关于通过引用的传递,所以

I already read up about passing by reference and so

procedure test(var x:integer);
begin
  x:=x+5;
end;

所以上面的代码通过引用更新5。我假设如果我通过引用更新数组,我可以声明 var X:数组blah ...有一些绑定的错误,只是想知道我是否应该使用数据类型的指针数据或如果指针总是int ...所以我知道如果我是如何做我的传递通过引用或其他在我的代码中的问题。

so the above code updates 5 by reference. I assumed if I was updating an array by reference I could declare var X: array of blah... having some bound bugs and just wanted to know if I should be using the type of data for the pointer to the data or if the pointer is always int... just so I know if it's how I'm doing my passing by reference or something else in my code that is the issue.

推荐答案

如果将动态数组作为非var参数传递,编译器将复制。

If you pass dynamic array as a non-var parameter, compiler will make a copy.

下面的小代码示例显示了通过在表单中​​显示37/42。

The small code sample below demonstrates that by displaying 37/42 in the form caption.

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以
$开头b $ b

If we look into the generated assembler code, IncArray1 starts with

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 8BC4             mov eax,esp

此代码将源数组复制到堆栈,并将eax设置为第一个元素的地址(=最后一次推送后存储在堆栈指针中的地址) 。堆栈长度下降,所以代码以最后一个元素开始(当调用IncArray1时,edx包含高(数据)),并重复(读取元素;推送元素;递减索引),直到它到达元素0。

This code copies source array to the stack and sets eax to the address of the first element (= address stored in the stack pointer after last push). Stack grows down so the code starts with the last element (edx contains High(data) when IncArray1 is called) and repeats (read element; push element; decrement index) until it gets to the element 0.

IncArray2不包含此类代码。在调用IncArray2和IncArray2之前,调用者将数据的地址存储到eax寄存器中。只需使用该地址。

IncArray2 contains no such code. Caller stores the address of the data into the eax register before calling IncArray2 and IncArray2 just uses this address.

如果您不想使用var原因,您可以将数据的地址传递给您的方法。但是,由于您不能在参数声明中使用语法data:^ array of integer,因此您必须为数据声明一个类型。而您必须在方法中使用'data ^'而不是'data'。

In case you don't want to use 'var' for any reason, you can pass an address of the data to your method. But as you can't use syntax 'data: ^array of integer' in parameter declaration, you'd have to declare a type for your data. And you'd have to use 'data^' instead of 'data' everywhere in the method.

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进行测试。

Tested with Delphi 2007.

这篇关于在Delphi中如何通过引用传递数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆