首页 > 解决方案 > 如何使用现有指针将指针分配给记录元素?

问题描述

我了解指针的概念以及如何使用,但我只是想澄清一下关于将指针分配给已经被另一个指针指向的记录子元素的一些困惑......

我在其他地方看到了一些我认为问同样问题的问题,但答案在 C 中......

如果我有:

type
  TDetails = record
     Name : string;
     Origin : string;
  end;

  TMsgData = record
     ID : string;
     Code : integer;
     Details : TDetails;
  end;

var
  MessageData = array of TMsgData;

我显然可以通过以下方式获得指向 TMsgData 类型的特定记录的指针:

var
  pMessageData = ^TMsgData;

begin
  pMessageData := @MessageData[0];
...

当然,然后我可以使用带有标准取消引用的指针访问所有记录元素。

但是,如何使用第一个指针获得一个新指针,该指针仅指向 MessageData[0] 的 Details 记录?我想避免有一个指向指针的指针,所以如果 pMessageData 是空闲的,我仍然有另一个指针。

如果我做

name := pMessageData.Details.Name;

然后 Delphi 会自动取消引用它来给我 name 的值。所以如果我这样做了:

var
  pMessageDetails = ^TDetails;

begin
  pMessageDetails = @pMessageData.Details;

*or*

  pMessageDetails = Addr(pMessageData^.Details);

其中任何一个都给了我指向原始记录的指针或新指针的指针吗?

标签: pointersdelphi

解决方案


让我们迂腐。

pMessageData是指向 a 的指针TMsgData。这意味着 thatpMessageData^是 a TMsgData,并且pMessageData^.Details是它的TDetails

因此,指向该记录的指针是@(pMessageData^.Details),也可以Addr(pMessageData^.Details)使用该Addr函数编写。

此外,@(pMessageData^.Details)解析方式与 相同@pMessageData^.Details,因此您可以省略括号。

实际上,您甚至可以省略解引用运算符并简单地编写@pMessageData.Details.


实际上,您可以使用 Delphi 本身轻松验证我的结论是否正确:

procedure TForm1.FormCreate(Sender: TObject);
var
  pMessageData: ^TMsgData;
  p1, p2, p3, p4: ^TDetails;
begin

  SetLength(MessageData, 3);

  MessageData[1].ID := 'Alpha';
  MessageData[1].Code := 123;
  MessageData[1].Details.Name := 'Test';
  MessageData[1].Details.Origin := 'NYC';

  pMessageData := @MessageData[1];

  p1 := @(pMessageData^.Details);
  p2 := Addr(pMessageData^.Details);
  p3 := @pMessageData^.Details;
  p4 := @pMessageData.Details;

  ShowMessage(p1^.Origin);
  ShowMessage(p2^.Origin);
  ShowMessage(p3^.Origin);
  ShowMessage(p4^.Origin);

  ShowMessage(NativeInt(p1).ToString);
  ShowMessage(NativeInt(p2).ToString);
  ShowMessage(NativeInt(p3).ToString);
  ShowMessage(NativeInt(p4).ToString);

  ShowMessage(NativeInt(@MessageData[1].Details).ToString); // same as last four

  ExitProcess(0)

end;

推荐阅读