1.什么是共用体
共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
2.共用体与结构体的存储
typedef struct
{
char A;
char B;
char C;
char D;
}ST;
typedef union
{
char A;
char B;
char C;
char D;
}UN;
同样的定义结构体和共用体,但是在内存中的存储是不同的。
简单来说,如果把结构体中的数据想象成每一个内存块的名字,那么共用体就是一个内存块有多个名字。
上面我们讨论的是共同体和结构体内部存储数据大小一致的情况,当存储的数据大小不一致时,共同体和结构体内部的数据是怎么存储的呢?
** 结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。** 共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
摘几句The C Programming Language里面讲述这个问题的原话,以说明读书还是必要的:
① 联合就是一个结构,
② 它的所有成员相对于基地址的偏移量都为0,
③ 此结构空间要大到足够容纳最“宽”的成员,
④ 并且,其对齐方式要适合于联合中所有类型的成员。
3.实际使用中的技巧
在实际的C语言编程中,我们使用共同体最常见的方式,是用共用体来管理传输中的位数据,也就是bit类型数据。
举个例子 :我们定义一个数据格式,其中最高位的bit代表传输方向,次高位的bit代表是否有后续帧,其余的bit三三一组代表数据发送与接收的计数器,那么数据结构如下
在这个结构中,我们可以将其定义为结构体形式也可以定义为共用体形式,由于共用体它的所有成员相对于基地址的偏移量都为0,而一个unsigned char 类型的数据存储的基地址是0bit 所占有的位置。
typedef struct
{
unsigned char RRR:3;
unsigned char TTT:3;
unsigned char FRAM:1;
unsigned char DIR:1;
}CONTROL;
typedef union
{
typedef struct
{
unsigned char RRR:3; //数据存储最低位
unsigned char TTT:3;
unsigned char FRAM:1;
unsigned char DIR:1; //数据最高位
}DATA;
unsigned char ALL;
}CONTROL;
对比上面两者的定义,均可以实现数据的准确存储,内存占用也完全一致,但是在数据的管理方面,后者要比前者更具有优势,在存时,可以直接将需要赋值的数据赋给ALL数据,在DATA内部就可以取出相应位的数据值,清空也很方便。
第一种定义方式也可以通过指针和长度来实现这种操作,但是直接操作存在一定的风险,此处不做讨论。
都看到这里了,如果有帮助,点个赞👍👍👍再走呗!
点个赞,代码没有Bug呦~