#include<stdio.h>
main()
{
union d
{
unsigned int a:1;
unsigned int b:3;
unsigned :0;
unsigned int d:1;
unsigned int e:1;
};
union d aa;
aa.b=9;
printf("d.aa.a=%d d.aa.b=%d",aa.a, aa.b);
system("pause");
}
在这个问题中,union的大小与为union分配的bit字段的数量不同。任何人都可以解释这个区别......剩下的内存会发生什么?
答案 0 :(得分:5)
关于包含位域的类型的大小,标准说(C11 6.7.2.1 p11):
实现可以分配足够大的任何可寻址存储单元来保存位字段。
由于这是union
,并且联合中的所有成员仅使用unsigned int
中不超过3位,union
的大小至少为char
大小如果union
,加上系统要求的填充(如果有的话)。在许多系统上,它会将每个单元填充到比特字段所采用的类型的大小,因此在这种情况下,我希望unsigned int
的大小与{{的大小相同1}}(尽管这可能是由于正常的union
填充要求而发生的。)
0
大小的位字段是union
中的红鲱鱼,但它在struct
(C11 6.7.2.1 p12)中具有特殊含义:
没有声明符但只有冒号和宽度的位字段声明表示 未命名的位域。作为特殊情况,宽度为0的位域结构成员 表示不会将其他位字段打包到放置了前一位字段(如果有)的单元中。
因此,如果您的union
改为struct
:
struct d
{
unsigned int a:1;
unsigned int b:3;
unsigned :0;
unsigned int d:1;
unsigned int e:1;
};
然后,此struct
的大小至少为2 char
s(如果需要,还有任何其他填充)。大多数情况下,它实际上会达到2 unsigned int
s的大小。
答案 1 :(得分:1)
计算机体系结构具有一定的字长。虽然如果正确使用,声明位字段可能是有效的,但如果字长是可变的则不会有效。我认为大多数编译器会出于效率原因填充位。简而言之,在大多数情况下,其余的位将丢失。
为简单起见,假设字长为8,并且在并集中使用2和3的位字段。我用字母来表示个别位。
a b c d e f g h
在我的示例中将使用前3位a,b和c,编译器将确保不使用其余位。
This可以用更好的词语来解释。
但是,在联盟中使用位字段?我不确定这是个好主意。
希望我的解释有所帮助。有疑问吗?
答案 2 :(得分:0)
面团!大小将填充到4个字节(在大多数实现中)
所以“a”指的是第一个(紧挨着第0位:-)位,“b”指前三位,“d”和“e”都指第一位所有的相同的32位(4字节)字。