Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1320110
  • 博文数量: 482
  • 博客积分: 13297
  • 博客等级: 上将
  • 技术积分: 2890
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-12 16:25
文章分类

全部博文(482)

文章存档

2012年(9)

2011年(407)

2010年(66)

分类: C/C++

2010-06-10 10:59:21

位域全解析 
        所谓”位域“是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。   
       它实际上是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个字节内的分配,如果涉及到跨字节的位域,则要进行另外的处理。这个问题我们稍后讨论。
阅读(856) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~