在结构体中允许存在位段、无名位段以及字对齐所需的填充字段。但是位段的用法,本身就具有一定的限制性,并不是简单的分配,期间还需要考虑到字对齐。系统默认的字对齐是4字节字对齐。
以下的一段示例代码,将帮助你理解位段的用法:
#include "stdio.h"
//session 1:结构体内部进行位段分配,但是只是分配一个字用于字段分配
//大小为8个字节,4字节对齐
struct pid_tag_small{
unsigned int inactive : 1;//为inactive分配1个bit
unsigned int : 1;//填充1个位
unsigned int refcount : 6;//为refcount分配6个bit
//unsigned int : 0;//填充到下一个字边界
unsigned int new_word : 1;//新的字,分配1个bit
short pid_id;
//struct pid_tag *link;
};
//session 2:结构体内部惊醒位段分配,分配两个字用于字段分配
//大小为12字节,4字节对齐
struct pid_tag_big{
unsigned int inactive : 1;//为inactive分配1个bit
unsigned int : 1;//填充1个位
unsigned int refcount : 6;//为refcount分配6个bit
unsigned int : 0;//填充到下一个字边界
unsigned int new_word : 1;//新的字,分配1个bit
short pid_id;
//struct pid_tag *link;
};
//session 3:将最后一个位段分配与前面部分位段分配隔开,
//系统将为其重新分配一个字用于位段分配
//大小为12字节,4字节对齐
struct pid_tag{
unsigned int inactive : 1;//为inactive分配1个bit
unsigned int : 1;//填充1个位
unsigned int refcount : 6;//为refcount分配6个bit
//unsigned int : 0;//填充到下一个字边界
short pid_id;
unsigned int new_word : 1;//新的字,分配1个bit
//struct pid_tag *link;
};
//session 4: 使用位段后面声明char,尝试与位段公用字
//但是结果还是12字节,4字节对齐。说明分配给位段的字是相对独立的,
//不与一般的类型变量公用同一个字,即使是单字节大小的char
struct pid_tag_char{
unsigned int inactive : 1;//为inactive分配1个bit
unsigned int : 1;//填充1个位
unsigned int refcount : 6;//为refcount分配6个bit
//unsigned int : 0;//填充到下一个字边界
char pid_id;
unsigned int new_word : 1;//新的字,分配1个bit
//struct pid_tag *link;
};
int main(int argc, char* argv[])
{
printf("Hello World!/n");
printf("%d/n", sizeof(struct pid_tag_small));
printf("%d/n", sizeof(struct pid_tag_big));
printf("%d/n", sizeof(struct pid_tag));
printf("%d/n", sizeof(struct pid_tag_char));
//conclusion :结构体中允许存在位段、无名位段以及字对齐所需的填充字段
//但是系统为位段分配的字是相对独立的,即使位段并未使用完4个字节
//也不会与一般的类型变量公用一个字,即使是单字节大小的char
//最后session 3可以看出,如果位段的声明不连续的话,
//系统会单独的为其分配一个字
//最后值得注意的是,位段的类型必须是int,unsigned int,signed int(或加上限定符)
//至于int位段的值可不可以取负值则取决于编译器
return 0;
}
运行结果:
8
12
12
12