gpt4 book ai didi

c - 这些指针取消引用之间有什么区别

转载 作者:太空宇宙 更新时间:2023-11-04 02:29:43 25 4
gpt4 key购买 nike

这类问题您确定它是重复的,但您需要提出。我不知道术语,所以我不知道要搜索什么,我只是根据我给出的示例询问正确的术语。

谁能给我解释一下这两者之间的区别(好吧,即使是正确的术语,我也可以自己谷歌一下):

UINT32 v32;
UINT32* v32_ptr = &v32;

UINT16 v16_1 = *(UINT16*)v32_ptr; // Version 1 of dereferencement
UINT16 v16_2 = (UINT16)*v32_ptr; // Version 2 of dereferencement

结果是一样的,但是用例呢?

最佳答案

在第一种情况下,您将一个 32 位指针转换为一个 16 位指针并取消引用它。在第二种情况下,您正在取消引用 32 位指针。

在这两种情况下,您都分配给一个 16 位变量。

结果并不总是相同的,这取决于体系结构的字节顺序。换句话说,如果体系结构是小尾数法,那么两个 16 位变量在源可以采用的整个值范围内应该相等。但如果架构是大端架构,值通常会有所不同。

编辑鉴于您在下方评论中提出的问题,我认为此处的示例会有所帮助。

考虑以下内容并假装架构可以选择它喜欢的字节序。此外,让我们使用值 0x4241,并让进程将其写出 4 次,交替使用大端/小端字节序,前两次为 UINT32,后两次为 UINT16。

address     data
0xABCD0000 00 00 42 41 // big-endian, UINT32, value 0x4242
0xABCD0004 41 42 00 00 // little-endian
0xABCD0008 42 41 // big-endian UINT16
0xABCD000A 41 42 // little-endian UINT16

最后两个是为了帮助可视化差异。

当我们将 v32_ptr 设置为 v32 的地址时,它接收到内存地址 0xABCD0000(例如)。该值在内存中布局 BE。如果我们将 v32_ptr 转换为 (UINT16*),内存地址不会改变,但现在只使用前两个字节。将该指针取消引用为 16 位指针将产生 0。但将其取消引用为 32 位指针将产生结果 0x4241。

现在对小端变量做同样的事情。这里我们的内存地址是 0xABCD0004 和 0xABCD000A。将 v32_ptr 设置为 0xABCD0004,并将其取消引用为 (UINT16*)(LE),您将获得值 0x4241。如果您取消引用 16 位 LE 指针(如地址 0xABCD000A),这与您将获得的值相同。

两种转换都会截断 32 位原始值,但我希望您现在可以看出区别。

最后

此信息在网络编程、嵌入式系统以及对等和客户端-服务器协议(protocol)中有应用。 Little-endian几乎是通用的,但仍然有系统是BE。此外,一些较旧的网络协议(protocol)明确选择使用 BE。而且,您的示例的一个特定应用程序可能是测试您正在运行的系统的字节顺序(用于可移植源代码)。即,设置 v32 = 0x4241,然后在双向取消引用后,如果 v16_1 和 v16_2 相同(它们都等于 0x4241),则系统为 LE,但如果它们不同(一个产生 0x4241,另一个产生 0),则系统是BE。

关于c - 这些指针取消引用之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45203916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com