File 这个Delphi PAnsiChar代码是什么意思?
我们都在一个项目中使用Delphi,并且已经使用了多年。 但我们从未见过以下语法与泛七线谱一起使用,也不知道它的意思:File 这个Delphi PAnsiChar代码是什么意思?,file,delphi,byte,File,Delphi,Byte,我们都在一个项目中使用Delphi,并且已经使用了多年。 但我们从未见过以下语法与泛七线谱一起使用,也不知道它的意思: buffer : PAnsiChar recInstance : Byte recX : smallint num_info : integer // buffer loaded from a file... num_info := 0; // next two lines are a mystery recInstance := By
buffer : PAnsiChar
recInstance : Byte
recX : smallint
num_info : integer
// buffer loaded from a file...
num_info := 0;
// next two lines are a mystery
recInstance := Byte(buffer[num_info*5]);
recX := Byte(buffer[num_info*5+1])+256*Byte(buffer[num_info*5+2]);
在调试器中,recX似乎只加载了2个字节,但语法似乎不匹配。Byte()
只是将一个字节大小值(此处为AnsiChar)转换为字节类型
最后一行代码由两个字节组成两字节变量recX
(但不考虑可能的溢出效应)
Byte()
只是将一个字节大小值(此处为AnsiChar)转换为字节类型
最后一行代码由两个字节组成两字节变量recX
(但不考虑可能的溢出效应)
PAnsiChar
始终具有一个很好的属性,您可以访问指向的AnsiChar
,以及以下AnsiChar
s,使用索引表示法,如数组(字节或AnsiChar
s)。这就是为什么在这里使用它
现在,在具有{$POINTERMATH}
的现代版本中,您更愿意使用PByte
,它启用了相同的索引
recInstance
分配偏移量处的字节numinfo*5
,recX
分配以下两个字节作为单个16位值
在当前版本中,可以这样编写:
buffer: PByte;
n: Integer;
...
n := num_info * 5;
recInstance := buffer[n];
recX := buffer[n+1] or (buffer[n+2] shl 8); // together a 16 bit value
正如Remy所暗示的,您可以使用以下命令一次读取所有三个字节:
type
PRec = ^TRec;
TRec = packed record
Instance: Byte;
X: Smallint; // a 16 bit (i.e. 2 byte) signed integer.
end; // total size: 3 bytes.
var
MyRec: TRec;
...
MyRec := PRec(@buffer[num_info * 5])^;
PRec
cast将@buffer[num_info*5]
返回的地址重新解释为指向TRec
的指针,然后(使用^
)取消引用,并将结果分配给MyRec
换句话说,@buffer[…]
是一个指针,PRec(…)
将其转换为PRec
类型的指针,PRec(…)^
获取该指针处的3个字节,就好像它是TRec
一样
MyRec.X
现在与recX
相同,MyRec.Instance
现在与原始代码中的recInstance
相同。PAnsiChar
始终具有可以访问所指向的AnsiChar
的良好属性,以及以下使用索引表示法的AnsiChar
s,如数组(字节或AnsiChar
s)。这就是为什么在这里使用它
现在,在具有{$POINTERMATH}
的现代版本中,您更愿意使用PByte
,它启用了相同的索引
recInstance
分配偏移量处的字节numinfo*5
,recX
分配以下两个字节作为单个16位值
在当前版本中,可以这样编写:
buffer: PByte;
n: Integer;
...
n := num_info * 5;
recInstance := buffer[n];
recX := buffer[n+1] or (buffer[n+2] shl 8); // together a 16 bit value
正如Remy所暗示的,您可以使用以下命令一次读取所有三个字节:
type
PRec = ^TRec;
TRec = packed record
Instance: Byte;
X: Smallint; // a 16 bit (i.e. 2 byte) signed integer.
end; // total size: 3 bytes.
var
MyRec: TRec;
...
MyRec := PRec(@buffer[num_info * 5])^;
PRec
cast将@buffer[num_info*5]
返回的地址重新解释为指向TRec
的指针,然后(使用^
)取消引用,并将结果分配给MyRec
换句话说,@buffer[…]
是一个指针,PRec(…)
将其转换为PRec
类型的指针,PRec(…)^
获取该指针处的3个字节,就好像它是TRec
一样
MyRec.X
现在与recX
相同,MyRec.Instance
现在与原始代码中的recInstance
相同。我将使用PSmallint
类型转换,而不是手动连接字节:recX:=PSmallint(@buffer[n+1])^
或更好,定义一个压缩记录,并将其转换为:type PRec=^TRec;TRec=压缩记录持续时间:字节;recX:Smallint;结束。。。var缓冲区:PAnsiChar{或PByte};rec:TRec。。。rec:=PRec(@buffer[num_info*5])^代码>@Remy:我想起来了。但我认为这并不能真正澄清问题,因为对于理解这里的PAnsiChar的用法有困难的人来说,PRec(@buffer[n])^
语法更难理解。我想让事情尽可能简单。偏移量是'num_info乘以5'吗?因为数据类型是指针,所以星号是让每个人都不满意的地方。@Remy:我用你的建议更新了答案。谢谢。@AIG:我怀疑这会让很多了解帕斯卡/德尔福的人失望<代码>*
仅用于乘法。指针是与^
一起声明和使用的,而不是与*
一起声明和使用的。这不是C或类似C的语言。你的评论有点像一个Pascal程序员问为什么那些C语言的人把他们所有的代码都放在评论里我将使用PSmallint
类型转换,而不是手动连接字节:recX:=PSmallint(@buffer[n+1])^
或更好,定义一个压缩记录,并将其转换为:type PRec=^TRec;TRec=压缩记录持续时间:字节;recX:Smallint;结束。。。var缓冲区:PAnsiChar{或PByte};rec:TRec。。。rec:=PRec(@buffer[num_info*5])^代码>@Remy:我想起来了。但我认为这并不能真正澄清问题,因为对于理解这里的PAnsiChar的用法有困难的人来说,PRec(@buffer[n])^
语法更难理解。我想让事情尽可能简单。偏移量是'num_info乘以5'吗?因为数据类型是指针,所以星号是让每个人都不满意的地方。@Remy:我用你的建议更新了答案。谢谢。@AIG:我怀疑这会让很多了解帕斯卡/德尔福的人失望<代码>*
仅用于乘法。指针是与^
一起声明和使用的,而不是与*
一起声明和使用的。这不是C或类似C的语言。你的评论有点像一个Pascal程序员问为什么那些C语言的人把他们所有的代码都放在评论里