C语言结构体位域的使用技巧
基本概念
- 在C语言中,位域(Bit Fields)是一种数据结构,它允许程序员访问内存中的单个位。位域通常用于硬件编程,例如嵌入式系统开发,因为它们允许程序员直接访问和控制硬件寄存器的特定位。位域在不同的编译器和平台上可能会有不同的内存对齐和打包行为,因此在移植代码时需要小心。
基本语法
-
struct { unsigned int member1 : n1; unsigned int member2 : n2; // ... 可以继续添加更多的位域成员 } yourStructName;
unsigned int
表示位域成员的数据类型,通常是unsigned int
,但也可以是signed int
或_Bool
。member1
和member2
是位域成员的名称。: n1
和: n2
指定了每个成员所占用的位数,n1
和n2
是介于1到数据类型大小之间的整数。
位域成员可以是无符号的或有符号的,取决于它们前面的关键字
unsigned
或signed
。如果省略了这些关键字,位域默认为无符号。位域成员的总位数不能超过它们所属的数据类型的大小。例如,如果使用
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就行!