这个 Union 和 Bit field 交互是如何工作的?

How does this Union and Bit field interaction work?

所以这是一个例子:

struct field
{
    unsigned int a : 8;
    unsigned int b : 8;
    unsigned int c : 8;
    unsigned int d : 8;
};

union test
{
    unsigned int raw;
    field bits;
};

int main()
{

    test aUnion;
    aUnion.raw = 0xabcdef;

    printf("a: %x \n", aUnion.bits.a);
    printf("b: %x \n", aUnion.bits.b);
    printf("c: %x \n", aUnion.bits.c);
    printf("d: %x \n", aUnion.bits.d);


    return 0;
}

现在运行我得到:

a: ef
b: cd
c: ab
d: 0

而且我想我真的不明白这里发生了什么。所以我将 raw 设置为一个值,因为这是一个联合,其他所有东西都从中提取,因为它们都被设置为小于 unsigned int?所以位域是基于原始的?但那是如何映射出来的呢?为什么在这种情况下是 d: 0?

如有任何帮助,我将不胜感激。

这是因为您的 unsigned int 的 32 位长度不够(所有 32 位都未设置),无法完全填充所有位字段值。因为它只有 24 位长,所以位字段 d 显示的是 00 的十六进制值。尝试一下

aUnion.raw = 0xffabcdef;

这将产生

a: ef 
b: cd 
c: ab 
d: ff

由于 dd 位字段占用位 24-32(在小端),除非已分配的 unsigned int 字段已分配了一个占用这些位集的值,否则该位字段位置不会'也显示值。

使用整数的十六进制表示是有用的,因为它清楚地表明整数的每个字节的值是什么。所以设置

aUnion.raw = 0xabcdef;

表示最低有效字节的值为0xef,第二低有效字节的值为0xcd,依此类推。但是你正在设置 unionraw 字段,这是一个整数,所以它有 4 个字节长。在前面的表示中,最重要的字节丢失了,所以它可以写成

aUnion.raw = 0x00abcdef;

(这就像明确表示一个整数 x = 420 百,0 千等等)。

您的联合字段分别表示整数 rawa =byte[0]b = byte[1]c = byte[2]d = byte[3],因为 在一个union 所有元素共享相同的内存位置。这是真的,因为你是 运行 你的代码在 little endian 架构中(最低有效字节在前)。

所以:

a = byte[0] of raw = 0xef
b = byte[1] of raw = 0xcd
c = byte[2] of raw = 0xab
d = byte[3] of raw = 0x00