指针是指向 LSB 还是 MSB?

Posted

技术标签:

【中文标题】指针是指向 LSB 还是 MSB?【英文标题】:Does a pointer point to the LSB or MSB? 【发布时间】:2012-08-12 16:45:43 【问题描述】:

如果我有以下代码:

int i = 5;
void * ptr = &i;
printf("%p", ptr);

我会得到 i 的 LSB 地址还是 MSB? 平台之间的行为会有所不同吗? C 和 C++ 之间有区别吗?

【问题讨论】:

这是未定义的行为。打印ptr 的唯一方法是使用%p,或者将其转换为intptr_t 并使用相应的打印格式宏。 【参考方案1】:

考虑int 的大小是4 个字节。始终&i 会为您提供这 4 个字节的第一个地址。

如果架构是小端,那么低位地址的 LSB 如下所示。

+------+------+------+------+ 地址 | 1000 | 1001 | 1002 | 1003 | +------+------+------+------+ 价值 | 5 | 0 | 0 | 0 | +-----+------+------+------+

如果架构是大端,那么低位地址的 MSB 如下所示。

+-----+------+------+------+ 地址 | 1000 | 1001 | 1002 | 1003 | +-----+------+------+------+ 价值 | 0 | 0 | 0 | 5 | +-----+------+------+------+

所以&i 将给出i 的LSB 地址,如果是小端或者它会给出i 的MSB 地址如果是大端

在混合端模式下,将为每个任务动态选择小端或大端。

下面的逻辑会告诉你字节序

int i = 5; 
void * ptr = &i; 
char * ch = (char *) ptr;

printf("%p", ptr); 
if (5 == (*ch))
    printf("\nlittle endian\n");
else
    printf("\nbig endian\n");

cc++ 的此行为相同

【讨论】:

【参考方案2】:

我会得到 i 的 LSB 地址还是 MSB?

这取决于平台:它将是最低寻址字节,可能是 MSB 或 LSB,具体取决于您平台的字节序

虽然这没有直接写在标准中,但这是第 6.3.2.3.7 节所暗示的内容:

当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。


平台之间的行为会有所不同吗?

是的


这里c和c++有区别吗?

否:它在 C 和 C++ 中都依赖于平台

【讨论】:

虽然我几乎可以肯定这是正确的 - 您能否为这些声明提供参考? @amit 我没有找到直接的确认,但标准确实在谈到转换为char 指针的部分中说“最低寻址字节”。 感谢您的努力。 这应该是公认的答案:)。【参考方案3】:

这取决于平台的字节顺序;如果是 little-endian 平台,您将获得指向 LSB 的指针,如果是 big-endian 平台,它将指向 MSB。甚至还有一些混合端平台,在这种情况下愿上帝怜悯你的灵魂检查编译器/CPU 的特定文档。

不过,您可以在运行时执行快速检查:

uint32_t i=0x01020304;
char le[4]=4, 3, 2, 1;
char be[4]=1, 2, 3, 4;
if(memcmp(&i, le, 4)==0)
    puts("Little endian");
else if(memcmp(&i, be, 4)==0)
    puts("Big endian");
else
    puts("Mixed endian");

顺便说一句,要打印指针,您必须使用 %p 占位符,而不是 %d

【讨论】:

请澄清我的小疑问。据我所知,混合端系统将为每个任务选择小端或大端。请告诉我你的porgram中else case的用途是什么。我对混合字节序的理解是否错误? “混合端”是一个包罗万象的术语,用于字节排序不是规范的大端或小端的架构(查看***的一些例子);我的代码只是检查该 32 位整数的内存表示是否与 big-endian 或 little-endian 系统的预期匹配,如果不匹配,则不会进一步调查,只是说它是混合端。跨度> 【参考方案4】:

ptr 存储整数对象的起始字节的地址。这是存储最高有效字节还是最低有效字节的位置取决于您的平台。一些奇怪的平台甚至使用混合字节序,在这种情况下它既不是 MSB 也不是 LSB。

在这方面,C 和 C++ 没有区别。

【讨论】:

ptr stores the address of the starting byte of the integer object. 你的意思是它总是给我们多字节数据的最低地址(比如int)?有内存向下增长的平台吗?【参考方案5】:

它指出的是我的 VC++ 2010 和 Digital Mars 的 MSB。但它与字节顺序有关。

这个问题的答案为您提供了一些信息: Detecting endianness programmatically in a C++ program.

这里,用户“none”说:

#define BIG_ENDIAN      0
#define LITTLE_ENDIAN   1
 int TestByteOrder()

   short int word = 0x0001;
   char *byte = (char *) &word;
   return(byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN);

这提供了一些字节序信息

【讨论】:

【参考方案6】:

我得到 i 的 LSB 地址还是 MSB?

这取决于机器和操作系统。在大端机器和操作系统上,您将获得 MSB,而在小端机器和操作系统上,您将获得 LSB。

Windows 总是小端。 x86 上的所有(大多数?)Linux/Unix 风格都是小端。摩托罗拉机器上的 Linux/Unix 是大端。 x86 机器上的 Mac OS 是小端。在 PowerPC 机器上,它是大端。

它在平台之间的行为不同吗? 会的。

c 和 c++ 之间有区别吗? 应该不会吧。

【讨论】:

以上是关于指针是指向 LSB 还是 MSB?的主要内容,如果未能解决你的问题,请参考以下文章

MSB与LSB的含义

MSB与LSB的含义

C++ 中 MSB ->LSB 和 LSB->MSB 的有符号 INT 转换

如何知道指针是指向动态还是静态分配的内存

指针free后还存在吗?

引用还是指针?