C 语言编程 — 构造数据类型 — 位域(bit field)

Posted 范桂飓

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C 语言编程 — 构造数据类型 — 位域(bit field)相关的知识,希望对你有一定的参考价值。

目录

文章目录

位域

在某些场景中,需要存储的数据长度很小,仅仅是几个 bit,不到一个 Byte,例如:存放一个开关量,只有 0 和 1 两种状态,使用到 1bit 空间即可。

为了节省存储空间,并使处理简便,此时可以使用位域(Bit field)数据结构。所谓 “位域” 就是把一个 Byte 中的 8 个 bits 人为的划分为几个不同的区域,并说明每个区域的名称以及所占的 bit 数目。

这样就可以通过一个 Byte 来存储多个不同的变量数值了。

声明定义位域类型

位域的本质是一种特殊的结构体,所以在大体的使用上类似,区别在于位域的划分上。

struct 位域结构体名 
    type [member_name]: width
    ...
;
  • type:只能为 int、unsigned int、signed int 这 3 种类型。

  • member_name(可选的):命名标识符。当不指定时,称为无名位域,或空域,这时它只用来作填充或调整位置,而不能直接使用。

  • width:位宽。由于位域不允许跨字节,因此位宽不能大于一个字节的长度(8bit)。如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,另外一些编译器可能会把大于一个域的部分存储在下一个字中。视乎于编译器的实现。

示例:位域结构体变量 data 占用了 2Byte(16bit)。

struct bs 
    int a:8;
    int b:2;
    int c:6;
 data;

示例:可以声明一个空域成员,表示不使用。

struct bs 
    unsigned a:4;
    unsigned  :4;    /* 空域,填 0 表示不使用 */
    unsigned b:4;    /* 刻意从下一单元开始存放 */
    unsigned c:4

位域结构体的成员

#include <stdio.h>

int main() 
    struct BS 
        unsigned a:1;
        unsigned b:3;
        unsigned c:4;
    ;

    struct BS  bit;
    struct BS* pbit;

    bit.a = 1;    /* 给位域赋整型值 1,数值没有超过位域 a 的 1bit */
    bit.b = 7;    /* 给位域赋整型值 7,数值没有超过位域 b 的 3bit */
    bit.c = 15;   /* 给位域赋整型值 15,数值没有超过位域 c 的 4bit */

    printf("%d, %d, %d\\n", bit.a, bit.b, bit.c);

    pbit = &bit;   /* 把位域结构体变量 bit 的地址赋给位域结构体指针变量 pbit */
    pbit->a = 0;   /* 结构体变量访问结构体成员 */
    pbit->b &= 3;  /* 与赋值运算 */
    pbit->c |= 1;  /* 或赋值运算 */
    printf("%d, %d, %d\\n", pbit->a, pbit->b, pbit->c);

    return 0;

运行:

$ ./main
1, 7, 15
0, 3, 15

以上是关于C 语言编程 — 构造数据类型 — 位域(bit field)的主要内容,如果未能解决你的问题,请参考以下文章

C语言-结构体与位域

C言语位域

C语言结构体中冒号的作用——位域

C语言中如何将16位结构体定义为4位和12位两部分

数据结构 -- 位域

C/C++ 位域知识小结