在我看来,你不太明白什么是工会。一个工会的成员是重叠的价值(换句话说,一个Count
工会共享相同的空间三个成员)。
假设,只是为了示范的目的,一个short
是16位(2个字节),一个float
为32位(4个字节)和一个double
为64位(8个字节),则联合是在8个字节尺寸。在little-endian格式中,num
成员表示前2个字节,weight
成员表示前4个字节(包括num
的2个字节),卷成员表示全部8个字节(包括2个字节的num
和weight
的四个字节)。
最初,你的工会装着垃圾,即一些未知的位模式,让我们来显示它像这样(十六进制):
GG GG GG GG GG GG GG GG // GG stands for garbage, i.e. unknown bit patterns
如果设置num
为2,则前两个字节是0x02
0x00
,但其他字节仍然是垃圾:
02 00 GG GG GG GG GG GG
如果你读weight
,你只是阅读的前四个字节,解释为float
,所以float
包含字节
02 00 GG GG
由于浮点值有完全不同的格式整型像short
,你无法预测这些字节(即表示特定的位模式)。它们不代表浮点值2.0f,这可能是你想要的。实际上,一个float
的“更显著”部分存储在高位字节,即在weight
的“垃圾”的一部分,因此它几乎可以是任何东西,包括一个NaN
,+infinity
,-infinity
等
同样如果你读volume
,你有一个double
一个由字节
02 00 GG GG GG GG GG GG
的,并且不一定代表2。0(尽管偶然,它可能会非常接近,如果巧合,正确的位被设置在正确的位置,并且如果低位在显示这样的值时被舍去)。
联盟并不意味着要进行从int
到float
或double
的适当转换。他们仅仅意味着能够为不同类型的值存储到同一类型,并从另一成员阅读为你设置只是意味着你重新诠释一些存在于工会的东西完全不同的位。你不是转换。
那么你如何转换?这是很简单的,不需要工会:如果通过“错误”的成员访问联合(即比它通过指定程序以外的其他成员),结果将依赖于语义
short num = 2;
float weight = num; // the compiler inserts code that performs a conversion to float
double volume = num; // the compiler inserts code that performs a conversion to double
不要指望未定义的行为被定义。 – chris
您只能将该联合的“short”部分设置为某个值。其余的将包含每次重新运行的随机数据。 – usr2564301
那么男孩假设要做什么?只需选择你苹果的重量从空气 –