代码改变世界

位域全解析

2009-09-14 00:33  Logic0  阅读(5602)  评论(0编辑  收藏  举报
我顶 字号:
        所谓”位域“是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。  
       它实际上是C语言提供的一种数据结构。
使用位域的好处是:  
       1.有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。这样节省存储空间,而且处理简便。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
        2.可以很方便的利用位域把一个变量给按位分解。比如只需要4个大小在0到3的随即数,就可以只rand()一次,然后每个位域取2个二进制位即可,省时省空间。

        由于没有其他硬件平台实验条件,所以下边的例子基于intel x86硬件平台,内存排列为高位到低位,有SUN SPARC或其他平台的兄弟可以自行实验下。
位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度;
下面先看一个例子
struct
{
      unsigned char x1:2;
      unsigned char x2:2;  
      unsigned char x3:2;
      unsigned char x4:2;  
} wy;

这个位域定义的意思是,结构体内有四个变量x1,x2,x3,x4,每个变量占2个二进制位,那你猜猜这个结构体占大多空间呢?是1个字节,因为共8个二进制位,也就是1个字节。这个可以自己sizeof()一下进行验证。是不是节省了空间呢。

那么来看下一个例子,实现的是上述位域的作用2
union wy
{
     struct
     {
          unsigned char x1:2;
          unsigned char x2:2;
          unsigned char x3:2;
          unsigned char x4:2;
     }cn;
     unsigned char s;
} tmp;

union是联合,联合的好处就是里边的所有变量都用的是一个内存空间,不理解的参见谷歌。
          也就是说s和结构体cn用的是一个内存空间,都是1个字节。这样就可以把s给按位分解。这个时候不知道你想没有想这样一个问题,按位分解,如何分解,从高位到低位还是从低位到高位,下边我们通过实验来得出结论。
看程序:
#include "stdio.h"

union wy
{
     struct
     {
          unsigned char x1:2;
          unsigned char x2:2;
          unsigned char x3:2;
          unsigned char x4:2;
     }cn;
     unsigned char s;
} tmp;

int main()
{
     tmp.s = 174;                           //二进制形式是10101110
     printf("tmp.s is %d\n",tmp.s);
     printf("x1 is %d\n",tmp.cn.x1);
     printf("x2 is %d\n",tmp.cn.x2);
     printf("x3 is %d\n",tmp.cn.x3);
     printf("x4 is %d\n",tmp.cn.x4);
     return 0;
}
输出的结果是2,3,2,2。
从这个结果我们就可以看出来,这个按位分解是从地位到高位的。对照表:
x4  x3  x2  x1
10 10  11  10
高位<----地位

       但是有一点必须注意的是,这是在1个字节内的分配,如果涉及到跨字节的位域,则要进行另外的处理。这个问题我们稍后讨论。