指针指向最低位还是最高位?

16

如果我有以下代码:

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

我将得到i的最低有效位地址还是最高有效位地址?
在不同平台上会有不同的结果吗?
在C和C++之间是否存在差异?


6
这是一种未定义行为。打印ptr的唯一方法是使用%p,或将其转换为intptr_t并使用相应的打印格式宏。 - Kerrek SB
6个回答

22
考虑到int的大小为4字节。始终&i将给出这4个字节中的第一个地址。
如果架构是小端序,则较低的地址将具有如下LSB。
        +------+------+------+------+
Address | 1000 | 1001 | 1002 | 1003 |
        +------+------+------+------+
Value   |   5  |    0 |    0 |    0 |
        +------+------+------+------+
如果架构是大端序,则较低的地址将具有如下MSB。
        +------+------+------+------+
Address | 1000 | 1001 | 1002 | 1003 |
        +------+------+------+------+
Value   |   0  |    0 |    0 |    5 |
        +------+------+------+------+
因此,如果是小端序,&i将给出i的LSB地址;如果是大端序,&i将给出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++ 都是相同的。


11

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

这取决于平台:它将是最低地址的字节,具体是 MSB 还是 LSB 取决于您平台的字节序

虽然标准没有直接写明,但这是由第6.3.2.3.7节隐含的:

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


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

是的。


C 和 C++ 之间是否有差异?

没有:在 C 和 C++ 中都是与平台相关的。


虽然我几乎确定这是正确的 - 你能否提供这些声明的参考资料? - amit
@amit 我没有找到直接的确认,但标准确实在谈论转换为 char 指针的部分中说了“最低寻址字节”。 - Sergey Kalinichenko
感谢您的努力,无论如何。 - amit
这应该是被接受的答案 :)。 - Rick

8

这取决于平台的字节序; 如果是小端平台,则会得到指向最低有效位的指针,如果是大端平台,则会指向最高有效位。甚至还有一些混合字节序的平台,在这种情况下,请检查您编译器/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


请澄清我的小疑问。据我所知,混合字节序系统将为每个任务选择小端或大端。请告诉我在您的程序中else语句的用途是什么。我的混合字节序理解是否有误? - rashok
“Mixed endian” 是一个用于指代字节序不符合大端或小端的架构的总称(请查看维基百科以了解一些示例);我的代码只是检查该32位整数的内存表示是否与大端或小端系统的预期值匹配,如果不匹配,则不会进一步调查并且只会提示它是混合字节序。 - Matteo Italia

6

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

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


ptr 存储整数对象起始字节的地址。你的意思是它总是会给我们多字节数据(如 int)的最低地址吗?有没有任何平台内存是向下增长的? - abhiarora

3

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

这个问题的答案为您提供了一些信息:在C ++程序中以编程方式检测字节序

在这里,用户“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);
}

这提供了一些关于字节序的信息


1
这取决于计算机和操作系统。在大端机器和操作系统上,您将获得MSB,在小端机器和操作系统上,您将获得LSB。
Windows始终是小端的。x86上的所有(大多数?)Linux / Unix版本都是小端的。Motorola机器上的Linux / Unix是大端的。x86机器上的Mac OS是小端的。在PowerPC机器上,它是大端的。
是的,它会在不同平台上表现不同。
可能没有在C和C ++之间有区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接