C语言位域浅析

   位段(bit-field)是以位为单位来定义结构体(或联合体)中的成员变量所占的空间。含有位段的结构体(联合体)称为位段结构。采用位段结构既能够节省空间,又方便于操作。

     位段的定义格式为:

     type  [var]: digits

      其中:

      type只能为int,unsigned int,signed int,char, unsigned char 五种类型之一,digits表示该位段所占的二进制位数

  位段长度digits不能超过类型type对应的数据类型占用的大小,如若type为char,则digits不能超过8,为int则digits不能超过32

      位段名称var是可选参数,可以省略

     一、位域的定义

  位域定义与结构体定义相仿,其形式为: 
  struct 位域结构名 
  {

    位域列表

   }; 
  其中位域列表的形式为: type  [var]: digits

  例如:

 1 struct data{     
 2 
 3     int a : 32;          //位段a,占32位
 4 
 5     char b : 5;             //位段b,占5位
 6 
 7     char c : 2;            //位段c,占2位,和b存储在同一个字节
 8 
 9     unsigned char : 6;          //无名位段,占6位
10 
11 };

注:位域可以无位域名,这时它只用来作填充或调整位置,无名的位域不能被访问

  二、位段的使用

    位域的使用和结构成员的使用相同,其一般形式为:位域变量名·位段名,也可定义一个指向位域的指针p,然后p->位段名使用,使用时需要注意:

    ①不能对位段进行取地址操作

    ②若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元开始存放

    ③若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int

    ④对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果

  三、位段在内存中的存储模式

    使用位域的主要目的是压缩存储,其大致规则为:

  1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

  2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

  3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,经实验VC采取不压缩方式,即即使前一个字段有空余位足够容纳后一个字段,后一个字段也当前一个字段           没有空余位,从前一个字段类型大小之后的新字节开始存储;

  4) 如果位域字段之间穿插着非位域字段,则不进行压缩;

  5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。:

 

  测试程序如下,环境vs3013,cfree 5.0

#include <stdio.h>

#include <stdlib.h>

struct data{     

    int a : 20;          //位段a,占20位

    char b : 3;             //位段b,占3位,不会和a压缩存储

    char : 0;           //无名位段

    unsigned char c : 5;  //位段c,占5位
};
int main()

{
    data test;
    data *ptest;
    ptest = &test;
    //两种方式访问位段
    test.a = 20;
    ptest->b = 5;

    //vc不压缩存储,占用8个字节,为其最宽基本类型成员大小的整数倍
    printf("sizeof(data): %d\n",sizeof(data));

    //test.b在输出时自动转化为整型,5(101)高位为1,扩展时高位连续补1,值为-3
    printf("test.a = %d\t test.b = %d\n",test.a, ptest->b);

    system("pause");
    return 0;

}

 

运行结果为:

sizeof(data): 8
test.a = 20 test.b = -3

 

  参考:

     http://www.cnblogs.com/dolphin0520/archive/2011/10/14/2212590.html

  http://blog.sina.com.cn/s/blog_3d8529400100istl.html

posted @ 2015-12-17 01:46  Water520  阅读(7505)  评论(1编辑  收藏  举报