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当てはまりません。)struct

于 2013-08-28T06:29:52.797 に答える
2

ユニオンのすべてのメンバーが同じメモリを共有することに注意してください。に割り当てるとB、の値も変更PIされます。

安全のために、最後に「書き込み」したフィールドからのみ「読み取る」必要があります。

あなたが望むのは構造であるように私には思えます。

于 2013-08-28T06:29:21.393 に答える
0

未定義の動作が発生していますが、舞台裏で起こっていることは次のとおりです。

x86 など、sizeof(int) < sizeof(double) のリトルエンディアン マシンを使用している。ほぼ確実に、このマシンは float/double に IEEE 754 フォーマットを使用します (最近ではほぼすべてのマシンが使用しています)。

B フィールドに書き込むと、PI の double の下位ビットが上書きされます。したがって、最初に 3.0 を に格納するとPI、 のように設定されます0x4008000000000000。次に、50 を に格納BするPI0x4008000000000032、たまたま 3.0000000000000220446049250313080847263336181640625 になります。これは 3.0 と等しくありませんが、デフォルトの精度で印刷すると、3.0 に丸められます。

于 2013-08-29T18:19:58.050 に答える