• 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
    ",sizeof(data));
    
        //test.b在输出时自动转化为整型,5(101)高位为1,扩展时高位连续补1,值为-3
        printf("test.a = %d	 test.b = %d
    ",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

  • 相关阅读:
    MySQL主从半同步复制
    MySQL主从之延时复制
    MySQL备份
    MySQL主从介绍及搭建(异步复制)
    MySQL物理备份Xtrabackup
    MySQL数据库误删除数据恢复
    MySQL--日志
    JAVA日报
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/yangcs/p/5052862.html
Copyright © 2020-2023  润新知