0

我正在使用 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

numbers.PI 的偶数值已经设置为 3,第一个“if”条件为 false。这种行为的原因是什么?

4

3 回答 3

5

原因是没有理由。

您的代码调用未定义的行为,因为您正在设置B联合成员:

numbers.B = 50;

但是在设置之后,您立即读出了另一个成员, PI

cout <<" numbers.PI :" << numbers.PI << endl;

也许您对联合和结构感到困惑——除非浮点数3和整数50在您的体系结构上具有相同的位表示(这不太可能),否则您对程序的期望行为只有在您使用 a 时才是合理的struct

union成员驻留在内存中的同一个位置 - 设置一个也会覆盖另一个。对于 a 来说不是这样struct,它的每个成员都存储在不同的内存位置。)

于 2013-08-28T06:29:52.797 回答
2

请记住,工会的所有成员共享相同的内存。当您分配给B您时,您也会更改的值PI

为了安全起见,您应该只从您“写入”到的最后一个字段中“读取”。

在我看来,你想要的是一个结构。

于 2013-08-28T06:29:21.393 回答
0

你得到未定义的行为,但这是幕后发生的事情:

您正在使用 sizeof(int) < sizeof(double) 的 little-endian 机器,例如 x86。几乎可以肯定,该机器使用 IEEE 754 格式进行浮点数/双精度(现在几乎所有机器都这样做)。

当您写入 B 字段时,它会覆盖 PI 中双精度的低位。因此,当您最初将 3.0 存储在 中PI时,会将其设置为0x4008000000000000. 然后,当您将 50 存储在B该更改PI中时0x4008000000000032,恰好是 3.00000000000002220446049250313080847263336181640625。所以这不等于 3.0,但是当您以默认精度打印时,它会将其四舍五入为 3.0

于 2013-08-29T18:19:58.050 回答