C 结构和整数的内存顺序

C 结构和整数的内存顺序,c,memory,struct,unions,C,Memory,Struct,Unions,我想与一个结构和一个uint64_t建立一个并集,这样我就可以用该结构引用单个uint16_t,并将它们连接到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 s

我想与一个结构和一个uint64_t建立一个并集,这样我就可以用该结构引用单个uint16_t,并将它们连接到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
这对我来说是违反直觉的(应该是0000123456789ABC或123456789ABC)。有人能解释一下为什么结构中的元素看起来是颠倒的吗

编辑:
供将来参考:endianness的答案让我感到困惑,因为uint16的打印顺序是正确的。当然,这是因为它们本身存储在little endian平台上。

您在little endian平台上,首先存储的字节(地址最低)最终位于组合的
uint64\t
的最低有效位(打印时位于右侧)

如果在big-endian平台上运行相同的代码,您将得到预期的结果。您的代码目前无法在具有不同终端的系统之间移植。

这一切都与。我不认为C/C++语言定义了这种工作方式,而是让实现/目标CPU来定义。在big-endian CPU上,您会得到您期望的结果。

如果您的处理器是“little-endian”,则LSB存储在最低地址,因此这是正常输出。在Intel的x86平台上,通常是little endian。相比之下,摩托罗拉的PowerPC是big-endian,也就是说,存储在最低地址的MSB

这是因为