1.位域的声明
位域变量的声明与结构变量声明的方式相同。 如:
struct sample
{
int a:7; //类型说明符 位域名:位域长度
int b:2;
int c:6;
}data;
其中,data为sample变量,共占两个字节。其中位域a占第一个字节的7位,位域b占第二个字节的低2位,位域c占第二个字节的高6位。
2.位域的对齐
如果结构体中含有位域(bit-field),那么VC中准则是:
1) 如果相邻位域字段的类型相同且其位宽之和小于声明数据类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同但其位宽之和大于类型的sizeof大小(如:char 的位域长度不能超过8,int的字节长度不能超过32),则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式(不同位域字段存放在不同的位域类型字节中),Dev-C++和GCC都采取压缩方式;
系统会先为结构体成员按照对齐方式分配空间和填塞(padding),然后对变量进行位域操作。
位域可以有无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:
struct sample
{
char a:7; //类型说明符 位域名:位域长度
char b:2;
char :2;
char c:2 //无位域名的位数 直接跳过且这2位不能使用
}data;
3、位段经典应用
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
struct A
{ //结构体字节长度为8 (1+3+4=8)//参照普通结构体对齐规则
char a:8; //占用第一个字节的8位 //1+3
unsigned int b:5; //占用第五个字节的低5位 //4
unsigned int c:3; //占用第五个字节的高3位
};
int main()
{
char testArry[10] = "0123456789";
char testB[10] = {0};
struct A d;
memcpy(&d, testArry, sizeof(d));
printf("%d ", sizeof(d));
printf("%d ", d.a);
printf("%d ", d.b);
printf("%d ", d.c);
system("pause");
return 0;
}
编译运行输出结果:8 48 20 1
00110111 00110110 00110101 00110100 00110011 00110010 00110001 00110000