pointers - 如何使用现有指针将指针分配给记录元素?
问题描述
我了解指针的概念以及如何使用,但我只是想澄清一下关于将指针分配给已经被另一个指针指向的记录子元素的一些困惑......
我在其他地方看到了一些我认为问同样问题的问题,但答案在 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);
其中任何一个都给了我指向原始记录的指针或新指针的指针吗?
解决方案
让我们迂腐。
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;
推荐阅读
- python - 弹性搜索 Kibana 标签云
- docker - Mayan-EDMS 不适用于 Redis 的默认值
- android - Kotlin 委托破坏导航
- node.js - 如何在nodejs中将csv文件从前端上传到s3
- mysql - 编写一个查询来计算每个订购产品的总值。列:ProductName、TotalAmountOrdered
- windows - Win 10 WSL 不会设置默认值 2
- linux - 从 Linux "ip a s" 显示以太网接口及其对应的 IP 地址
- node.js - MongoDB按Node.JS mongodb驱动程序中的自定义计算排序
- xamarin - ScrollView 内的选项卡切换组件内的 CollectionViews - Xamarin Forms
- entity-framework-core - 自动外键创建