当前位置:  开发笔记 > 编程语言 > 正文

如何在Delphi中通过引用传递数组?

如何解决《如何在Delphi中通过引用传递数组?》经验,为你挑选了2个好方法。

我已经读过关于通过引用传递等等

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

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



1> gabr..:

如果将动态数组作为非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 8BC4             mov eax,esp

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

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

如果您因任何原因不想使用'var',可以将数据地址传递给您的方法.但是,由于您无法在参数声明中使用语法'data:^ array of integer',因此您必须为数据声明一种类型.而且你必须在方法中的任何地方使用'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测试.



2> Loren Pechte..:

加布尔的答案是正确的,但关键点深埋得足以让我把它作为一个单独的帖子把它拿出来:

首先定义您的类型!在这种特定情况下,编译器接受了一个整数数组,但这仅仅是因为它具有特殊含义并且它不是您所期望的.在过程定义中定义类型的任何其他尝试都将失败.

与C不同,如果要将两个事物分配兼容,则必须将它们声明为SAME类型,而不仅仅是两个构建相同的类型:

Var
     A : Array [1..4] of Integer;
     B : Array [1..4] of Integer;

Begin
    A := B;

不会编译.而是:

Type
    Array4 = array [1..4] of Integer;

Var
    A : Array4;
    B : Array4;

Begin
    A := B;

并且编译器会执行您期望的操作.


如果运行gabr的代码,但所有"整数数组"都被TIntArray替换(其中TIntArray =整数数组),那么数组总是通过引用传递,而数据[0]是37 + 5 + 5 = 49.Inn那有点奇怪吗?
推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有