3 回答
TA贡献1876条经验 获得超6个赞
该标准回答了C ++标准9.5节或C99标准第6.5.2.3节第5段(或C11标准的第6段或C18标准的6.7.2.1节第16段)中的所有问题:
在联合中,最多可以在任何时间激活一个数据成员,即,最多可以在任何时间将一个数据成员的值存储在一个联合中。[注:为了简化并集的使用,做出了一项特殊保证:如果POD联合包含多个共享共同初始序列(9.2)的POD结构,并且此POD联合类型的对象包含以下一个: POD结构,允许检查任何POD结构成员的公共初始序列;见9.2。联合的大小足以容纳其最大的数据成员。每个数据成员都被分配为好像它是结构的唯一成员。
这意味着每个成员共享相同的存储区域。这里是活跃在最一个成员,但你不能找出哪一个。您将不得不将有关当前活动成员的信息自己存储在其他地方。除了联合以外,还存储这样的标志(例如,将具有整数作为类型标志的结构并将联合作为数据存储区)将为您提供所谓的“区分联合”:知道哪种类型的联合它目前是“活跃的”。
词法分析器的一种常见用法是,您可以具有不同的令牌,但是根据令牌的不同,您可以存储不同的信息(放入line每个结构以显示常见的初始序列是什么):
struct tokeni {
int token; /* type tag */
union {
struct { int line; } noVal;
struct { int line; int val; } intVal;
struct { int line; struct string val; } stringVal;
} data;
};
该标准允许您访问line每个成员,因为这是每个成员的共同初始序列。
存在一些编译器扩展,这些扩展允许访问所有成员,而不管当前存储了其值的成员。这样可以有效地重新解释每个成员之间具有不同类型的存储位。例如,以下内容可用于将float变量分解为2个无符号短裤:
union float_cast { unsigned short s[2]; float f; };
在编写低级代码时,这可能非常方便。如果编译器不支持该扩展名,但是您仍然这样做,则编写未定义结果的代码。因此,如果使用该技巧,请确定您的编译器对此有支持。
TA贡献1934条经验 获得超2个赞
一个a union总是占用最大成员的空间。现在使用什么都没关系。
union {
short x;
int y;
long long z;
}
上面的一个实例union将始终至少需要a long long进行存储。
附注:由于注意到斯特凡诺,实际空间的任何类型(union,struct,class)将采取不依赖于其他问题,如编译器对齐。我并不是为了简单起见,因为我只想告诉我工会考虑了最大的项目。重要的是要知道实际大小确实取决于alignment。
- 3 回答
- 0 关注
- 587 浏览
添加回答
举报