背景
在一次代码阅读中发现了c语言的位域和联合体的联合使用,看的不是很明白,故做笔记记录。
开头
遇到的代码内容如下:
typedef struct _tag_Uart_Drv_Data
{
unsigned char a : 2;
unsigned char b : 2;
unsigned char c : 2;
unsigned char d : 2;
unsigned char e : 2;
unsigned char f : 2;
unsigned char g : 2; //4 5 2^4=16
unsigned char h : 2;
unsigned char i : 2;
unsigned char j : 2;
unsigned char k : 2;
unsigned char l : 2;
unsigned char m : 2;
unsigned char n : 2;
unsigned char o : 2;
unsigned char p : 2;
unsigned char q : 8;
unsigned char r : 8;
unsigned char s : 8;
unsigned char t : 8;
unsigned char u : 8;
} ;
typedef union _tag_Uart_Drv_DataBuf
{
struct _tag_Uart_Drv_Data Bits;
uint8_t _c[9]; //signa + checksum
}uart_dev;
结论
在一番的查资料后了解到,这里使用了C语言中的位域(bit-field)分表表示给每个变量赋值长度为2bit或8bit的长度的内存空间。
让我们再次看到结构体下面的联合体(union)中定义的内容,这里有一个结构体定义的变量Bits
以及一个uint8_t型的数组_c
,由union的定义可知,这两个成员变量指向的是内存中的同一片区域,也就是说对这两个变量的读写,实际上是指向内存的同一片区域,换句话说,当我们在对Bits
中的成员变量进行改变时可以直接通过下面的数组来进行读,每8bit
代表其中数组的一个变量,故我们可以在Bits
中对成员变量赋值,在_c
中对改变的变量进行读操作,这样可以大大地提高数据的读效率,尤其是在串口通信中的信息传输时。
注意:这里的abcd 4位代表的是数组_c[0]
,因为这8位刚和数组下标0的地址是相对应的。