2013-03-11 51 views
2

我想与一个结构和一个uint64_t进行联合,所以我可以引用单个uint16_ts与结构,并将它们串联在uint64_t中。我在此测试程序:结构和整数的内存顺序

#include "stdio.h" 
#include "stdint.h" 
struct test_struct{ 
    uint16_t stuff; 
    uint16_t a; 
    uint16_t b; 
    uint16_t c; 
}; 

union test_union{ 
    struct test_struct str; 
    uint64_t uint; 
};  

int main(){ 
    struct test_struct x = { 
     .stuff = 0x0000, 
     .a = 0x1234, 
     .b = 0x5678, 
     .c = 0x9ABC 
    }; 
    union test_union y; 
    y.str = x; 

    printf("y.uint: %llX\n", y.uint); 
} 

输出成为:

y.uint: 9ABC567812340000 

其是反直觉的,我(它是768,16 000ABC,或123456789ABC)。有人可以向我解释为什么结构中的元素似乎被颠倒了吗?

编辑: 供将来参考:字节顺序的答案让我感到困惑,因为uint16_ts是按照正确的顺序打印的。但是,这当然是因为它们本身存储的是小端。

回答

7

您处于一个小端平台,首先存储的字节(地址最低)结束于组合的uint64_t的最低有效位(右侧打印时)。

如果你在一个big-endian平台上运行相同的代码,你会得到你期望的结果。现在的代码不能在具有不同字节顺序的系统上移植。

0

这一切都与Endianess。我不认为C/C++语言定义了这种工作方式,而是将它留给实现/目标CPU来定义。在一个大端的CPU上,你会得到你所期望的。

0

如果你的处理器是“小端”,LSB存储在最低地址,所以这是一个正常的输出。在英特尔的x86平台上,通常它是小端的。相比之下,摩托罗拉的PowerPC是大端,也就是说,MSB存储在最低地址。