何时进行C联合

时间:2014-08-09 22:31:43

标签: c++ c compiler-construction unions

如果C中的并集用于将变量打包到字节数组中,如下所述:

typedef union 
{ 
uint16_t integer; 
byte binary[4]; 
} binaryInteger;

实际工会何时执行?是否将变量分配给union的任何部分。或者是在访问该部分时?

当前或以前的分配(取决于执行的时间)是否可以以任何方式访问而不会导致联合执行?

4 个答案:

答案 0 :(得分:6)

我不清楚你执行联盟的意思。

每当您将数据放入其中一个字段时,数据就会被放入内存中。然后,访问另一个字段,您将使用相应字段的解释读取相同的数据。

例如,问题中的联合需要4个字节。前2个字节也映射到整数。

+----+----+----+----+
|    |    |    |    | raw bytes
+----+----+----+----+
|    |    |           integer
+----+----+

如果将0x1234的值放入整数,则数组的前两个字节分别设置为0x120x34。 (顺序取决于系统的字节顺序。)

OTOH,如果您设置bytes[0]和/或bytes[1],则会立即影响integer的值。

答案 1 :(得分:6)

在C和C ++中,联合会是被动的,因此从技术上讲,它们永远不会“执行”。它们告诉编译器如何为union控制的类型执行内存布局。

编译器在编译时计算union的大小(这是其最大成员的大小)。然后,当您对union的成员进行分配时,会在内存中放置数据。

答案 2 :(得分:2)

您的问题无法得到解答,因为工会实际上并未执行过#34;。

当你用机器语言编写程序时,你所拥有的只是一堆字节,你告诉计算机如何处理这些字节。哪个可以"将该地址后面的4个字节视为有符号整数,并将它们加5#34;或者其他什么。

像C这样的高级语言会保留有关某些字节所具有的数据类型的信息,以便让您更轻松(例如,您只需说myVar = 5而不必说assign4ByteSignedInteger(myVar,5)之类的内容。 1}})。当C编译成实际的机器语言时,它会自动为您提供的类型选择合适的机器指令,例如到一个局部变量。

通常,这很好,你想要那么方便。工会是一种语法糖,可以让你打破这个" type-safety-net"有选择地,如果您知道某些字节有两个用途。工会在设计时为工程师服务。对于计算机,他们可能也不存在。

所以Unions不是操作,它们只是类型指令。就像你不能说"什么时候执行int",你不能对联盟说同样的话。

答案 3 :(得分:0)

从技术上讲,编译器只会将两个不同的字段(在本例中)放在同一个地址。最大的成员(在这种情况下是4个字节的数组)确定union的总大小。

现在,还有一些关于联合的复杂规则以及如何访问这些字段,所以在这种情况下,binarychar的变体,它应该没问题如果我们使用的话是binary[0]binary[1]中的几个字节:

联盟x    {       int a;       浮b;    };

使用x.a = 0x3f800000;并不能保证cout << x.b << endl;打印1.0或类似的东西。除了char数组(可以是无符号)之外,所有其他类型都要求您访问最初存储的相同字段,或者它是未定义的行为。因此,在这种情况下,union只能用于“存储不同类型的数据”,但您确实需要知道它是union的每个实例的哪种数据。在具有可能以某种方式具有两种不同表示的结构的情况下节省空间仍然是一个强大的功能。

请注意,未定义的行为很糟糕,因为它似乎可以工作,然后您更改编译器,更改编译器设置,更改代码本身或类似的东西,突然,代码的行为有所不同。