0.简介
本篇介绍位域和一些不容易注意到的特性。
1.位域
一般在结构体的变量声明中用位域,例如
struct A
{
int a : 5, b : 3, c : 6, x : 5;
};
这时候,a,b,c,x冒号后面数字的意义是这个变量占用几个位,分别是5,3,6,5。因为声明的时候是int类型,这四个变量的位的总和不超过一个int的宽度,那么他们就共同占用一个int的位置,实验为32位程序,那么这个结构体的大小为4字节。并且如下操作也是不允许的。
sizeof(A::a);
abcx从头到以此来瓜分int中的位,一共占用19个位。如果是如下情形。
struct A
{
int a : 5, b : 3, c : 6, x : 5;
int d : 14;
};
我增加了一个d变量,占用14位,和a的组合起来是33位,刚好比int的32位多1位,此时,d会由于前一个int的剩余位置不够而单独开辟一个新的32位空间供d使用,此时结构体A中由两个int单元组成,占用8字节。对于其他类型也如此,例如下面的结构体。
struct B
{
char a : 5;
char d : 6;
};
B结构体共占用2字节。混合一下不同类型试一试。
struct B
{
short a : 4;
short b : 4;
short c : 4;
short x : 3;
short d : 1;
};
上面这个结构体的大小是2字节,因为正好占用一个short16位,下面这个呢。下面这个结构体的最后一个是char,此时虽然也能正好凑够2字节,但是由于类型变化了,所以此时这个是4字节,其中short是2字节,char占用1字节,然后对齐到4字节。
struct B
{
short a : 4;
short b : 4;
short c : 4;
short x : 3;
char d : 1;
};
还有一个特别的情况。
struct C
{
short a : 4;
short b : 4;
short c : 4,:0;
short x : 3;
char d : 1;
};
结构体C中,出现了长度为0的位域,此时,a,b,c共用一个short,由于c和x之间有一个0位域间隔,所以x重新占用一个新的short空间,由于d和x的类型不同,d单独占用一个char,此时一共是5字节,自动对齐后C结构体6字节。由于abc共同构成一个short,所以对与abc三个变量的并发修改是不安全的。