C 结构体之位域(位段) | C Bit Fields

来源:互联网 发布:vb for循环 跳出 编辑:程序博客网 时间:2024/05/16 05:35

概述

    有些信息在存储时,并不需要占用一个完整的字节,

    而只需占用几个或一个二进制位。

    例如在存放一个开关量时,只有 0 和 1 两种状态,用一位二进位即可。

    为了节省存储空间,并使处理简便,

    C 语言又提供了一种数据结构,称为 Bit Fields,翻译为“位域”或“位段”。


    所谓“位域”是把一个字节中的二进制位划分为几个不同的区域,并说明每个区域的位数。

    每个域有一个域名,允许在程序中按域名进行操作。

    这样就可以把几个不同的对象用一个字节的二进制位域来表示。

位域的定义  

    1.位域的定义与结构体定义相仿,其形式为: 

        struct 位域结构名 
        {
            位域列表
        };


    其中位域列表的形式为:
        类型说明符 位域名:位域长度;

    2.实例:
        struct bs      // 位域结构名为 bs
        {
         int a:8;    // 位域名为 a;
                        // 位域长度为 8,单位为 bit,即占用 8 个二进制位
         int b:2;
         int c:6;
        }; 

对于位域定义的几点说明

    1.位域类型

        在 gcc 中编译测试得知,

        位域的类型可以是:char short int long,不支持 float double;

        至于复杂类型,以及其他编译器的情况,搁置;

        如果使用了不支持的类型,gcc 编译时报错:错误: 位段‘*’类型无效

        实例:
            struct bs
            {
                char c:1;
                short s:1;
                int i:1;
                long l:3;

                float j:1;       //错误: 位段‘j’类型无效
                double k:1;     //错误: 位段‘k’类型无效

            };

    2.位域名
        没什么可说的,除了一点:

            位域可以无位域名,这时它只用来作填充或调整位置。

            另外无名的位域是不能使用的。
    3.位域长度
        1)位域长度指定了此位域的长度,单位为 bit;

        2)位域长度必须是非负整数值(a nonnegative integer value),

           且当且仅当无位域名时位域长度方可取 0 值;

           否则 gcc 报错:错误: 位段‘*’宽度为负 或 错误: 位段‘*’宽度为 0

        3)位域长度不能超过它自身的类型所占的位数,

           否则 gcc 编译报错:错误: ‘*’的宽度超过它自身的类型

        实例:
            struct bs
            {
             int a:-1;    // gcc 编译报错:错误: 位段‘a’宽度为负
                int b:0;     // gcc 编译报错:错误: 位段‘b’宽度为 0
             int c:33;    // gcc 编译报错:错误: ‘c’的宽度超过它自身的类型
                int d:32;   // 正确
                int :0;      // 正确
                int :2;      // 正确
                int e:1;     // 正确 
            }; 

位域变量的声明

    位域变量的声明与结构体变量的声明的方式相同。

    可采用先定义后声明、同时定义声明、直接说明这三种方式。 
 
    实例:

        1.先定义后声明
            struct bs
            {
             int a:8;
             int b:2;
             int c:6;
            }; 
           
struct bs data;
   
        2.同时定义声明
            struct bs
            {
             int a:8;
             int b:2;
             int c:6;
            } data; 
  
        3.直接说明
            struct
            {
             int a:8;
             int b:2;
             int c:6;
            } data;
            直接说明方式无非就是省去位域结构名,而直接给出位域结构变量。

位域的使用

位域的对齐

原创粉丝点击