1. 联合体
《C++ Primer Plus》第六版中关于联合体的描述是:共用体(union)是一种数据格式,它能够存储不同的数据类型,但只能同时存储其中的一种类型。
联合体(union)(即共用体)的声明格式如下:
union MyUnion
{
int iA;
double dA;
char cA;
};
关键字union表示MyUnion是一个联合体,MyUnion是一种用户自定义的数据类型,其使用方法如下:
MyUnion Ua;
Ua.iA=10;
根据《C++ Primer Plus》第六版的描述,联合体的用途之一是:当数据项使用两种或更多种格式(但不会同时使用)时,可节省空间。
那么这句话是真么意思呢?请看接下来的这段代码:
union MyUnion
{
int iA;
char cA;
};
#include <iostream>
using namespace std;
int main()
{
MyUnion UTestUnion;
UTestUnion.iA=42;
cout<<UTestUnion.cA<<endl;
return 0;
}
这段代码声明了一个名为MyUnion的联合体,main()函数里对MyUnion变量UTestUnion里的iA进行赋值42的操作。此时UTestUnion的iA等于42,那么UTestUnion的cA等于多少呢?以下是程序的输出结果:

为什么输出结果是“*”呢?
原因就是联合体内的元素公用同一个内存。
将上述代码稍作修改,如下:
union MyUnion
{
int iA;
double dA;
char cA;
};
#include <iostream>
using namespace std;
int main()
{
MyUnion UTestUnion;
UTestUnion.dA = 42.35;
double* dTest = (double*)&(UTestUnion.cA);
cout << *dTest << endl;
return 0;
}
上述程序中,dTest是一个double类型的指针,指向UTestUnion.cA的地址,该地址进行过强制类型转换,原本的char类型,被转换成double类型。在进行解引用时,获得该处地址存储的值。
程序输出结果为42.35, 正是赋给UTestUnion的double元素dA的值。
之所以能够这样输出,就是因为联合体中的元素共用同一个内存。UTestUnion的dA被赋值42.35,存入到内存,char类型的元素cA也表示这个内存中的值。只不过由于char类型和double类型在计算机中的存储方式不同,虽然cA和dA都表示同一内存中的值,但是存储方式不一样,因此直接取其值会表现相异。
下图是在VS2019中对该程序打断点调试的结果:

从图中调试的结果可以看到,iA的值不知道是啥,cA的值在"?"格式(未知格式)的编码下为-51。但是对cA的地址进行强制类型转换变成double类型地址之后,dTest的值就变成了正常的42.35。这正是因为dA和cA共用一个内存,将cA地址变成double型之后,其活动元素就变成了dA,因此以下语句:
(double*)&(UTestUnion.cA);
实际上等于
&(UTestUnion.dA)
小结
联合体很有意思,肯定还有很多功能尚未被笔者发现,万一某位大佬有更深的见解,欢迎留言指导!
1353

被折叠的 条评论
为什么被折叠?



