C语言结构体位域的使用技巧(联合体妙用)

C语言结构体位域的使用技巧

基本概念

  • 在C语言中,位域(Bit Fields)是一种数据结构,它允许程序员访问内存中的单个位。位域通常用于硬件编程,例如嵌入式系统开发,因为它们允许程序员直接访问和控制硬件寄存器的特定位。位域在不同的编译器和平台上可能会有不同的内存对齐和打包行为,因此在移植代码时需要小心。

基本语法

  • struct {
        unsigned int member1 : n1;
        unsigned int member2 : n2;
        // ... 可以继续添加更多的位域成员
    } yourStructName;
    
    • unsigned int 表示位域成员的数据类型,通常是 unsigned int,但也可以是 signed int_Bool
    • member1member2 是位域成员的名称。
    • : n1: n2 指定了每个成员所占用的位数,n1n2 是介于1到数据类型大小之间的整数。

    位域成员可以是无符号的或有符号的,取决于它们前面的关键字 unsignedsigned。如果省略了这些关键字,位域默认为无符号。

    位域成员的总位数不能超过它们所属的数据类型的大小。例如,如果使用 unsigned int(通常是32位),则所有位域成员的位数总和不能超过32位。

举例

  • #include <stdio.h>
    
    struct BitField {
        unsigned int is_enabled : 1;   // 占用1位
        unsigned int has_data   : 1;   // 占用1位
        unsigned int error_code : 6;   // 占用6位
        unsigned int mode       : 2;   // 占用2位
        unsigned int reserved   : 22;  // 占用22位,通常用于对齐或保留
    };
    
    int main() {
        struct BitField myBitField;
        myBitField.is_enabled = 1;
        myBitField.has_data = 0;
        myBitField.error_code = 31; // 只有最低6位会被使用
        myBitField.mode = 3;
    
        printf("is_enabled: %d\n", myBitField.is_enabled);
        printf("has_data: %d\n", myBitField.has_data);
        printf("error_code: %d\n", myBitField.error_code);
        printf("mode: %d\n", myBitField.mode);
    
        return 0;
    }
    

但是

  • 嵌入式一般在搞寄存器的时候会用到位域,像上面这个例子,但是我没法把 myBitField 这个结构体当成数值来用,除非用指针强转,但是这个行为存在危险性。那么怎么搞?嘿嘿,整个联合体就好了。

    typedef union {
        struct {
            unsigned int is_enabled : 1;   // 占用1位
        	unsigned int has_data   : 1;   // 占用1位
        	unsigned int error_code : 6;   // 占用6位
        	unsigned int mode       : 2;   // 占用2位
        	unsigned int reserved   : 22;  // 占用22位,通常用于对齐或保留
        } Bits;
        unsigned int  Value;
    } Super;
    

    联合体(union)的一个主要特性是它所有的成员都占用相同的内存位置。这意味着,你改结构体就是在改Value。给结构体赋完值以后,直接用Value就行!

  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值