我正在使用c ++进行联合, 以下是代码段:
#include<iostream>
using namespace std;
typedef union myunion
{
double PI;
int B;
}MYUNION;
int main()
{
MYUNION numbers;
numbers.PI = 3;
numbers.B = 50;
cout <<" numbers.PI :" << numbers.PI << endl;
if(numbers.PI == 3.0)
{
cout <<"True";
if(numbers.B == 50)
{
cout <<" numbers.PI :" << numbers.PI << endl;
cout <<" numbers.B :" << numbers.B << endl;
}
}
return 0;
}
输出是:
numbers.PI :3
数字的偶数值.PI已设置为3,首先“if”条件为false。 这种行为的原因是什么?
答案 0 :(得分:5)
原因是没有理由。
您的代码调用未定义的行为,因为您正在设置union的B
成员:
numbers.B = 50;
但在设置之后,您立即宣读其他成员 PI
:
cout <<" numbers.PI :" << numbers.PI << endl;
也许你让工会和结构混淆 - 除非浮点数3
和整数50
在您的架构上具有相同的位表示(这是非常的不太可能),只有当您使用struct
时,您对程序的期望才会合理。
(union
成员驻留在内存中的同一位置 - 设置一个也会覆盖另一个。对于struct
,每个成员都存储在不同的内存位置,这不是真的。 )
答案 1 :(得分:2)
请记住,联盟的所有成员共享相同的内存。当您分配到B
时,您也会更改PI
的值。
为了安全起见,您应该只从“写入”的最后一个字段“读取”。
在我看来,你想要的是一个结构。
答案 2 :(得分:0)
你正在获得未定义的行为,但这是幕后发生的事情:
你正在使用sizeof(int)&lt;的小端机器。 sizeof(double),例如x86。几乎可以肯定,该机器使用IEEE 754格式的浮点/双(这些天几乎所有机器都这样)。
当您写入B字段时,它会覆盖PI中双精度的低位。所以
当您最初在PI
中存储3.0时,会将其设置为0x4008000000000000
。然后,当您将B
中的50存储为PI
更改为0x4008000000000032
时,恰好是3.00000000000002220446049250313080847263336181640625。因此,它不等于3.0,但是当您使用默认精度打印时,它会将其舍入为3.0