union是什么
union叫做联合体(也叫做共用体),是C语言中的一种类型。与结构体相似,其中可以添加成员,但不同的是这些成员共用同一段内存。
struct Data{
int i;
char cr[4];
} data;
union Demo{
int i;
char cr[1];
} demo;
data所占的内存大小是8个字节,demo所占的内存大小是4个字节。
为什么会有union,它使用来解决什么问题的?
- 节省内存
如嵌入式开发之类内存紧张的情况下会考虑这个问题,使用union可以节省内存开销。 - 简化类型转换
看了一些网上的说明,还没有形成自己完整的理解,先记录一下当前的认识。
某些情况,传输/记录数据的时候使用的是某种类型(如char),但是实际表征的是其他类型的数据(如int)。此时的一般操作是需要进行转换,但是如果使用了union,则直接可以使用另一种类型的成员去直接访问.
有一篇文件讲述的稍微详细一点,大家可以参看,同时感谢作者。先附上原文链接:https://blog.csdn.net/debugzzj/article/details/81705755
设想用C语言实现这样一个功能。我需要用单片机读取一个监控温度的i2c slave的寄存器数据。这个寄存器是12位有效位寄存器。读出来之后我们要通过数据手册给定的公式计算成实际温度(设想这个公式为 temp = reg_val *10)。我们怎么实现呢?要知道,i2c的数据传输是按照byte传送的,也就是说,你只能用char类型结束数据,说白了,每个时序你只能接收8个bit的数据。所以12个bit需要读两次,用两个char类型变量或一个char类型数据接收。
读出寄存器数据(这个不在这篇文章的讨论范围内)
将读出的数据转换成可计算的数据类型(两个char类型转换成一个short或int或float类型)
根据公式计算
下面看一下不用union实现的函数
int fun( void )
{
int tmp_value = 0;
char reg_val[2] = {0,0};
....
i2c.read(addr<<1, reg_val, 2);
tmp_value = (reg_val[1]<<8 | reg_val[0]);
return tmp_value*10;
}
用union的
union REG_VAL {
int value;
char buf[2];
}reg_val;
int fun( void )
{
int tmp_value = 0;
char reg_val[2] = {0,0};
....
i2c.read(addr<<1, reg_val.buf, 2);
return reg_val.value*10;
}
基本了解了union的使用背景之后,接下来了解一下union的使用。
union的设计原则
- union可以定义多个成员,其大小由最大成员的大小决定。
- union成员共享同一块大小的内存,一次只能使用其中的一个成员。
- 对某一个成员赋值,会改变其他成员的值。
- union的存放顺序是 所有成员都从低地址开始存放。
union的使用
- 变量定义
union 共用体名
{
成员表列
}变量表列;
union Data
{
int i;
char c;
float f;
} a, b, c;
- 共用体变量的引用
a.i
a.c
a.f