规则:
1. 位域不能跨字节,所以位域的长度不能超过8bits
2. 所以当一个字节所剩空间不够存放另一位域时,就要从下一字节起存放新的位域
3. 可以有意使某位域从下一字节开始,这就需要用到无名位域,这种无名位域只用来作填充或调整位置。
struct ss
{
int a1:1; /*第一个字节*/
int :2; /*空出两位*/
int a3:3;
int a4:2;
int b1:3; /*第二关字节*/
int :0; /*空出第二个字节剩下的位域*/
int c1:4; /*从第三个字节开始分配*/
};
4. 位域的类型通常是char,int, unsigned.
5. 位域的取值, 需要从名字来取,不能通过bit来取, 因为little-endin和bit-endin的存储排位是不一样的
例如下面的代码, 在Wintel平台和SunSparc平台上打印出来的结果是不一样的。
#/:cat t.c
#include <stdio.h>
union uu {
char ch;
struct {
int a:3;
int b:2;
int c:3;
} ss;
};
void printb(char c)
{
printf("char('%c')=%d(0x%x)=",c,c,c);
int d;
for (int i=0;i<sizeof(c)*8;i++)
{
d = 1<<(7-i);
d &= c;
printf("%d",d==0?0:1);
}
printf("/n");
}
int main()
{
union uu u;
u.ss.a = 1;
u.ss.b = 2;
u.ss.c = 3;
printb(u.ch);
}
SunSparc平台上输出:
char('3')=51(0x33)=00110011
a b c
Wintel平台上输出:
char('q')=113(0x71)=01110001
c b a
可以看出他们对a,b,c的位域分布正好相反。