结构和整数的记忆顺序

时间:2013-03-11 13:34:16

标签: c memory struct unions

我想与struct和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

这对我来说是违反直觉的(它应该是0000123456789ABC,或123456789ABC)。有人可以向我解释为什么结构中的元素似乎被颠倒了吗?

编辑: 为了将来参考:endianness答案让我感到困惑,因为uint16_ts以正确的顺序打印。但是,这当然是因为他们自己存储的是小端。

4 个答案:

答案 0 :(得分:7)

您使用的是小端平台,首先存储的字节(具有最低地址)最终位于组合uint64_t的最低有效位(打印时右侧)。

如果您在big-endian平台上运行相同的代码,您将获得预期的结果。您的代码不能在具有不同字节序的系统之间移植。

答案 1 :(得分:0)

这与Endianess有关。我不认为C / C ++语言定义了它的工作方式,而是由实现/目标CPU来定义。在大端CPU上,你已经得到了你所期望的。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

这是因为Little Endianess