1、union(共用体)
1.1、概述
C 语言中,union是一种数据类型,对比于结构体,结构体中的每个成员都占用独立的内存空间,而联合中所有的成员都共享同一个内存空间。
也就是说,union中的不同成员要表示的是同一个变量的不同数据类型。
1.2、代码
#include <stdio.h>
union data{
int n;
char ch;
short m;
};
int main(){
union data a;
printf("%d, %d\n", sizeof(a), sizeof(union data) );
a.n = 0x40;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.ch = '9';
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.m = 0x2059;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.n = 0x3E25AD54;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
return 0;
}
注意:
1、union的存储空间以最大的成员为准,成员定义中最大的是int n,所以为4个字节。
2、图中的ch,n,m共用了4字节的内存空间。(根据大小端不同,存放顺序会不一致)
3、修改其中的一个成员,会覆盖原有数据,而造成其他成员的变化。
2、位域
2.1、概述
在定义结构体时,我们可以指定某个成员变量所占用的二进制位数(Bit)。
- 成员变量的类型限制最大的二进制位数。
- “:”后指定该成员变量所占用的二进制位数。
2.2、代码
struct bit_field {
unsigned int a : 1;
unsigned int b : 2;
unsigned int c : 5;
};
这个结构体有三个成员变量 a、b 和 c,它们分别占用 1 位、2 位、5 位二进制位。
2.3、特殊说明
-
位域成员变量的访问速度并不一定比一般的成员变量快,因为有些编译器不支持单个位域的直接操作,需要先将整个位域读入CPU寄存器中,然后进行各种“位运算”操作。
-
对于位域成员变量,不能取地址运算符(&)对其进行取址操作,因为它们并不按字节对齐,取址操作会得到一个编译错误。
3、混合使用的代码及解释
union
{
u16 wDevSta ;
struct
{
unsigned char bRegister:1;
unsigned char bONLine:1;
unsigned char bReConnect:1;
unsigned char bLowBAT:1;
unsigned char bConfig:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
unsigned char b9:1;
unsigned char b10:1;
unsigned char b11:1;
unsigned char b12:1;
unsigned char b13:1;
unsigned char b14:1;
unsigned char b15:1;
} ch;
}g_DevStatus;
定义了一个union类型的变量g_DevStatus,包含了一个u16 wDevSta和一个嵌套的结构体成员ch。
在结构体成员ch中,有16个位域变量,每个位域变量都只占用1位,分别用来表示设备的不同状态,取值为0或1。
例如,如果要将设备的bONLine状态设置为1,可以使用以下2种代码:
g_DevStatus.ch.bONLine = 1;
g_DevStatus.wDevSta |= (1<<1);