zoukankan      html  css  js  c++  java
  • C位域操作

    位域的概念

    1个字节包含8位,有些变量保存的数据不需要占用这么长的空间(比如bool类型,只有两个状态true和false, 1位就可以搞定,剩下的7位就浪费了),这就催生了“位域”结构,位域将1个字节划分成不同的区域,每个区域都有个位域名,程序员可以代码通过位域名访问其中的数据。

    位域的声明

    类型 位域名:位域长度;

    位域结构体,我理解是一种特殊的结构体,其成员变量都是位域,声明如下

    struct 位域结构名 
    {
      类型说明符 位域名:位域长度;
      ...
      类型说明符 位域名:位域长度;
    };

    基本原则

    现有一个简单的结构体

    typedef struct Test1
    {
        char a:1;
        int b:2;
    }test1;

    1. 位域变量的长度不能大于其类型的长度(sizeof(类型) * 8)

    48264b03-3f3d-49dc-ade5-4785ed836cb8

    变量char has_assoc的类型位char 1字节 8位,小于定义的10,所以编译器警告

    2.  不能用于位域字段的操作:取地址操作符&,取偏移量操作

    位域是若干位空间,是没有地址的

    53a51dac-cfce-476d-842a-8dd83b231bb6

    3. 位域可以是无名位域,无名位域只能用作填充或调整位置,不能使用。

    typedef struct Test1
    {
        char a:1;
        int b:2;
        int :1;
    }test1;

    4. 位域字段不能声明为类的静态成员

    5. 位域结构体的大小必须是其最长基本类型大小的整数倍(sizeof(类型) * 8)

    6.如果一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如: 

    struct bs     
    {     
        unsigned a:4     
        unsigned :0 /*空域*/     
        unsigned b:4 /*从下一单元开始存放*/     
        unsigned c:4     
    }

    这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。

    7.不够一个类型的size时,将按其中最大的那个类型对齐。

    struct foo4 {
        char    a : 2;
        char    b : 3;
        int c : 1;
    };

    foo4中虽然三个位域所占用空间之和为6 bit < 8 bit(1 byte),但是由于char和int的对齐系数是不同的,是不能捆绑在一起,那是不是a、b捆绑在一起按照char对齐,c单独按照int对齐呢?我们 打印一下sizeof(struct foo4)发现结果为8,也就是说编译器把a、b、c一起捆绑起来并以int做对齐了。

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

    typedef struct Test1
    {
        char a:1;
        int b:2;
    }test1;
    //运行结果:4
    typedef struct Test1
    {
        char a:1;
        int b:2;
        long c;
    }test1;
    //运行结果:16

    总结:

    1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止
    2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
    3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,GCC采取压缩方式;
    4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
    5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
  • 相关阅读:
    图片处理帮助类
    网站前端的优化
    状态码大全
    服务端性能监控工具Nmon使用方法
    jmeter测试报告解析
    jmeter聚合报告
    jmeter跨线程组调用参数
    jmeter生成测试报告
    Jmeter获取cookie
    monkey的使用方法和常见命令
  • 原文地址:https://www.cnblogs.com/WindSun/p/11283910.html
Copyright © 2011-2022 走看看