delphi指针问题

发布于 2024-11-30 12:48:14 字数 1050 浏览 0 评论 0原文

我有以下正在运行的代码,但我不能 100% 理解它(请参阅代码中的注释):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TMyRec=record
    a:Integer;
    b:String;
  end;
  TRecArray=array of TMyRec;
  PRecArray = ^TRecArray;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
   v1:TRecArray;
   procedure Test(a:PRecArray);
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
 SetLength(v1,3);
 v1[0].b:='test1';//set the first value
 Test(PRecArray(v1));//call method to change the value assigned before
end;

procedure TForm1.Test(a: PRecArray);
begin
 ShowMessage(v1[0].b);//shows test1
 try
  a^[0].b:='test2' //this is raising an error...
 except

 end;
 PRecArray(@a)^[0].b:='test3';//this is working...
 ShowMessage(v1[0].b);//shows test3
end;

end.

我不明白为什么 'a^[0].b:='test2' 会引发错误。

谢谢你!

I have the following code which is working, but I don't understand it 100% (please see the comments from code):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TMyRec=record
    a:Integer;
    b:String;
  end;
  TRecArray=array of TMyRec;
  PRecArray = ^TRecArray;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
   v1:TRecArray;
   procedure Test(a:PRecArray);
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
 SetLength(v1,3);
 v1[0].b:='test1';//set the first value
 Test(PRecArray(v1));//call method to change the value assigned before
end;

procedure TForm1.Test(a: PRecArray);
begin
 ShowMessage(v1[0].b);//shows test1
 try
  a^[0].b:='test2' //this is raising an error...
 except

 end;
 PRecArray(@a)^[0].b:='test3';//this is working...
 ShowMessage(v1[0].b);//shows test3
end;

end.

I don't understand why 'a^[0].b:='test2' is raising an error.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

过气美图社 2024-12-07 12:48:14

您的“测试”过程需要一个“PRecArray”,但您要向它传递一个“TRecArray”。尝试像

 Test(@v1);//call method to change the value assigned before

将“TRecArray”类型转换为“PRecArray”那样调用它不会使其成为“PRecArray”。 (注意:你的“test3”当然会失败。)

Your 'Test' procedure expects a 'PRecArray', but you're passing a 'TRecArray' to it. Try calling it like

 Test(@v1);//call method to change the value assigned before

Typecasting a 'TRecArray' to a 'PRecArray' will not make it a 'PRecArray'. (Note: your 'test3' will fail then of course.)

归属感 2024-12-07 12:48:14

我看到一些可疑的事情。

1

几乎不需要使用指向动态数组的指针,因为动态数组变量已经是指针(嗯,参考文献)。

要将这样的数组传递给函数或过程,请使用 var 参数:

procedure TForm1.Test(var a: TRecArray);

现在您不必使用指针语法来访问该数组:

a[0].b := 'test2';

2

您可以使用以下方式调用 Test:

Test(PRecArray(v1));

在原始版本中,Test 采用了PREcArray,但您没有传递一个(您传递的是 TRecArray),所以您应该这样做:

Test(@v1); // or Test(Addr(v1));

应用上面的更改,其中 Test 有一个 var 参数,只需使用:

Test(v1);

3

好的,这可能是不值得怀疑,但我想插入我的文章寻址指针,关于 Delphi 程序员的指针。它解释了您似乎遇到的许多问题。

I see several things that are suspicious.

1

There is hardly ever a need to take a pointer to a dynamic array, as dynamic array variables are already pointers (well, references).

To pass such an array to a function or procedure, use var parameters:

procedure TForm1.Test(var a: TRecArray);

Now you don't have to use pointer syntax to access the array:

a[0].b := 'test2';

2

You call Test with:

Test(PRecArray(v1));

In your original, Test took a PRecArray, but you are not passing one (you are passing a TRecArray), so you should have done:

Test(@v1); // or Test(Addr(v1));

Applying my change above, where Test has a var parameter, simply use:

Test(v1);

3

Ok, this is probably not suspicous, but I'd like to plug my article Addressing Pointers, about pointers for Delphi programmers. It explains many of the issues you seem to have.

临走之时 2024-12-07 12:48:14

您可以

procedure TForm1.Test(a: TPointerArrayRec);

用更简单的方式

   procedure TForm1.Test(var a: TArrayRec);   

替换,并且不必使用 deprecation 取消引用运算符 ^。

You could replace the

procedure TForm1.Test(a: TPointerArrayRec);

with

   procedure TForm1.Test(var a: TArrayRec);   

it's simpler and you don't have to use the deprecation dereference operator ^.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文