'int' 和 'int *' 指向哪个字节?

To which byte of `int` an `int *` points?

提问人:apadana 提问时间:11/13/2023 更新时间:11/13/2023 访问量:89

问:

A 指向内存地址最低的字节,而不是最不重要的字节。这是正确的吗?我总是忘记这一点,不得不重新学习它。我在网上搜索了几分钟,但没能找到答案(当然我的搜索时间还不够长)。int *int

C 指针

评论

1赞 tkausl 11/13/2023
是的。为什么这很重要?
0赞 apadana 11/13/2023
@tkausl,因为我们希望编写的代码无论硬件的字节序如何都能正常工作。
2赞 bazza 11/13/2023
为了很好地处理字节序,最好坚持使用值运算符,而不是指针操作。例如,要获取 int 的 LSB,请使用 ,而不是计算指向 LSB 的指针。如果您需要可靠地从文件/流中读取/写入数据,请使用 Google Protocol Buffers 之类的工具,而不是直接从内存中写入数据。这将为您解决所有和任何字节序问题。i & 0x000000ff
0赞 Weather Vane 11/13/2023
如果它是一个,那么你将不会读取一个字节,而是读取整个整数,所以它如何存储并不重要,除非它说,一个使用不同字节序的文件头。如果您正在处理硬件多字节寄存器,则读取或写入它们的顺序可能很重要,因此您可能希望单独读取这些字节(使用 )。int*uint8_t *
0赞 i486 11/13/2023
“我总是忘记这个”——当你再次忘记它时,总是在这里发布问题。

答:

3赞 Marco Bonelli 11/13/2023 #1

A 指向内存地址最低的字节,而不是最不重要的字节int *int

是的,我认为这是一种体面的记忆方式。

我这样说是为了让它更笼统:指向对象的指针指向内存中对象的开头

现在,对于类似的整型类型,系统的字节序决定了内存中字节的顺序,因此 的开头可能是端系统上的最高有效字节 (MSB)、小端系统上的最低有效字节 (LSB),甚至是其他东西。intint

评论

2赞 ShadowRanger 11/13/2023
然后你就会有所谓的“中间端”(或“混合端”)系统的怪异之处。在这一点上,这完全是历史性的,但这是一个有趣的怪癖,如果你正在做可怕的事情,包括将数据的原始表示存储到文件中并期望它被其他系统读取,你必须考虑。
0赞 Marco Bonelli 11/13/2023
@ShadowRanger好的观点,我总是忘记像这样疯狂的系统存在(或已经存在):')
0赞 Craig Estey 11/13/2023
你忘了 Unix 的鼻祖 PDP-11 了吗?你真丢人:-)
1赞 Lundin 11/13/2023 #2

是的,如果您将该指针的内容打印为原始二进制文件,它将打印指向的最低地址。int

但严格来说,an 是一个内置了某种类型知识的指针。如果执行类似操作,则无论 如何存储在内存中,都将始终屏蔽掉最低字节。这意味着大多数运算符都可以在取消引用的指针上可移植使用,而无需关心内容的存储位置。int**ptr & 0xFFint

例如,此代码在小端和大端之间是可移植的:

unsigned int i = 0x11223344;
unsigned int* ptr = &i;
printf("%X\n", *ptr & 0xFF);     // always 44
printf("%X\n", *ptr>>24 & 0xFF); // always 11

(用于避免符号和按位运算符的各种问题)unsigned

而下面的代码是不可移植的,因为它按地址顺序打印原始二进制文件:

unsigned char* cptr = (unsigned char*)&i;
printf("%X\n", *cptr);     // 44 or 11
printf("%X\n", cptr[3]);   // 44 or 11

如果是小端序,我们会得到 44 11,如果是大端序,我们会得到 11 44。