我想与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以正确的顺序打印。但是,这当然是因为他们自己存储的是小端。
答案 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。