位域定义
位域定义和结构体struct 类似
struct 位域结构名
{
// 位域列表
type [name] : width ;
};
位域列表中各个元素的描述:
tpye: 类型只能是int(整型),unsigned int(无符号整型),signed int(有符号整型)
[name]: 位域的名字,遵循变量的命名规则,[]方括号是可选的,如果没有名字,那么代表空域,该位域是不可用的,类似于占位
width: 位域占这种类型的多少个位,width 的大小应该小于等于type类型所占内存大小,比如int 32位, width 必须小于等于32
struct flag
{
int debug : 1; // 使用一位来存储是否是debug模式
};
位域的使用
位域变量名.位域名
位域变量名->位域名
flag fg; // 普通变量
fg.debug = 1;
flag* pfg; // 指针
pfg->debug = 1;
位域所占内存的大小
位域所占内存的大小 = 所有位域宽度之和 / sizeof(type) 的商向上取整 在乘sizeof(type)
size = ceil(width / sizeof(type)) * sizeof(type)
struct flag
{
int debug : 1;
int show_cursor : 1;
};
struct flag_1
{
int debug : 1;
int show_cursor : 32;
};
int main()
{
printf("flag size %d\n", sizeof(flag));
printf("flag_1 size %d\n", sizeof(flag_1));
}
输出
flag size 4
flag_1 size 8
位域与联合体组合
位域与联合体组合的威力可以同时把所有的位都重置为0,清空位域很是方便
union flag
{
struct
{
int debug : 1;
int show_cursor : 1;
};
int all;
};
// 转化为二进制输出
void print(int flag)
{
char s[33] = {'0'};
itoa(flag, s, 2);
printf("flag %s\n", s);
}
int main()
{
flag f;
//清空所有位
f.all = 0;
print(f.all);
f.debug = 0;
f.show_cursor = 1;
print(f.all);
f.all = 0;
f.debug = 1;
f.show_cursor = 1;
print(f.all);
return 0;
}
输出
flag 0
flag 10
flag 11
所赋值超过位域大小之后会发生什么
如果赋的值大于该位域可以表示的最大值,则该位域的值会被截断,而不是转换为0或者1。
比如宽度为1的位域只能标识0 或者1, 那么我赋值3就会被截断,
3 的二进制为 11, 最终被截断只有一位,把截断这位赋值给位域。所以所赋值千万不要大于width的宽度,不然会有意想不到的bug。