联合体union能解决什么问题?_数据



《《《《《正文》》》》》




《结构体的不足》

在C语言中,如果要你描述一辆车的属性,最快最简洁的方法就是构建结构体:








struct car_info{     char *logo; //品牌     long country; //国家     int price;   //价格     char type; //类型};

如上定义的结构体就可以很方便的描述一辆车的信息,而且多辆车的话只需新增一个car_info定义的变量而已,方便且简洁明了!

如果后续还增加车的属性的话,只需在结构体中增加一个参数就可以了,如下:






struct car_info{     ...    int color; //颜色};

但是有没有想过,新能源车和传统型车之间的属性不同,就是新能源有的参数在传统型车上是没有的,比如电池充电速度、电池容量等属性;同样,传统型车上有的属性是新能源车上没有的,比如用油类型等属性;

那有人说,简单,新能源和传统车型各开一个结构体:



















struct NewCar_info{     char *logo; //品牌     long country; //国家     int price;   //价格     char type; //类型     int  timer;//充电速度     int  batery; //电池容量};
struct OldCar_info{ char *logo; //品牌 long country; //国家 int price; //价格 char type; //类型 int oiltype;//用油类型 int Oilspend; //耗油量};

这样子,只要调用定义就可以了,如下:






// 新能源车型struct NewCar_info Ninfo;// 传统车型struct OldCar_info Oinfo;

不过,在程序里讲究封装这个概念,我们往往喜欢把相同的东西封装打包,这样能节省很多空间,而且下次更改也只需更改封装里的东西,不必全代码一个一个的更改,所以干脆就写成一个结构体吧,如下:












struct NOCar_info{     char *logo; //品牌     long country; //国家     int price;   //价格     char type; //类型     int  timer;//充电速度     int  batery; //电池容量     int  oiltype;//用油类型     int  Oilspend; //耗油量};

如上结构体,依然可以描述新能源车型和传统车型,如下:






// 新能源车型struct NOCar_info Ninfo;// 传统车型struct NOCar_info Oinfo;

上面只要特殊处理一下,新能源不能访问传统属性,传统不能访问新能源的属性就可以了,但是他们之间耦合会增加很多,这样也是行得通的;

但是因为今天是讲union,自然要挑骨头,有人会说,嵌入式本来内存就紧张,上面这种方法浪费内存,听起来无可反驳,那怎么办?



《union大显身手》

union的出现就很好解决了浪费内存和耦合高的问题,我们来看看,它是怎么解决的。

先来看看union的语法:




















struct NewCar_info{     int  timer;//充电速度     int  batery; //电池容量};struct OldCar_info{     int  oiltype;//用油类型     int  Oilspend; //耗油量};struct NOCar_info{     char *logo; //品牌     long country; //国家     int price;   //价格     char type; //类型    union{        struct NewCar_info NCar;        struct OldCar_info OCar;    };};

我们来看NOCar_info中的union内的参数,意思就是其中的2个struct公用一块内存,什么意思呢?就是你改变 struct NewCar_info NCar中的值,struct OldCar_info OCar也会被同样改变,且是同一个内存同一个值,反过来亦是如此,因此成为共用体、联合体;


如上我们只需一个结构体,就可解决新能源和传统车型自己的属性不同问题;




// 新能源、传统struct NOCar_info NO_Car;

若要访问新能源车型的充电时间和电池容量,可如下操作:




timer = NO_Car.NCar.timer;batery = NO_Car.NCar.batery;

若要访问传统车型的用油类型和油耗量,可如下操作




oiltype = NO_Car.OCar.oiltype;Oilspend = NO_Car.OCar.Oilspend;

这样子就解决了,上面的浪费内存,耦合读高的问题;


union当然也有其他的用处,主要原理是利用公用内存这一个特性;



《我常用union的场景》

串口发送往往是按字节发送,因此一个32位的数据,需要拆分成4个字节,然后依次发送;按往常,我们做位运算可以得出4个字节的数据,但是union就可以直接取出,具体实现伪代码如下:

























typedef union{  uint8_t    B8[4];  uint16_t   B16[2];  uint32_t   B32;}B32_B8_TypeDef;
uint32_t Send_Data = 0x12345678;B32_B8_TypeDef Uart_Send;
void main(void){ //数据复制 Uart_Send.B32 = Send_Data; //字节复制 Uart[0]= Uart_Send.B8[0]; Uart[1]= Uart_Send.B8[1]; Uart[2]= Uart_Send.B8[2]; Uart[3]= Uart_Send.B8[3]; //发送数据}


《《《《《END》》》》》

联合体union能解决什么问题?_数据