这个 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
,依此类推。但是你正在设置 union 的 raw
字段,这是一个整数,所以它有 4 个字节长。在前面的表示中,最重要的字节丢失了,所以它可以写成
aUnion.raw = 0x00abcdef;
(这就像明确表示一个整数 x = 42
有 0
百,0
千等等)。
您的联合字段分别表示整数 raw
的 a =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
所以这是一个例子:
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
,依此类推。但是你正在设置 union 的 raw
字段,这是一个整数,所以它有 4 个字节长。在前面的表示中,最重要的字节丢失了,所以它可以写成
aUnion.raw = 0x00abcdef;
(这就像明确表示一个整数 x = 42
有 0
百,0
千等等)。
您的联合字段分别表示整数 raw
的 a =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