1.コンソーシアム
「C ++ Primer Plus」の第6版でのユニオンの説明は、次のとおりです。ユニオンは、さまざまなデータ型を格納できるデータ形式ですが、同時に格納できるのはそのうちの1つだけです。
ユニオン(つまり、ユニオン)の宣言形式は次のとおりです。
union MyUnion
{
int iA;
double dA;
char cA;
};
キーワードunionは、MyUnionが共用体であり、MyUnionがユーザー定義のデータ型であり、その使用法が次のとおりであることを示します。
MyUnion Ua;
Ua.iA=10;
「C ++ Primer Plus」の第6版の説明によると、コンソーシアムの用途の1つは、データ項目が2つ以上の形式を使用する場合(同時にではない場合)にスペースを節約することです。
では、この文は本当にどういう意味ですか?次のコードを参照してください。
union MyUnion
{
int iA;
char cA;
};
#include <iostream>
using namespace std;
int main()
{
MyUnion UTestUnion;
UTestUnion.iA=42;
cout<<UTestUnion.cA<<endl;
return 0;
}
このコードは、MyUnionという名前の共用体を宣言します。main()関数は、MyUnion変数UTestUnionのiAに値42を割り当てます。この時点で、UTestUnionのiAは42に等しいので、UTestUnionのcAは何ですか?プログラムの出力は次のとおりです。出力が
「*」なのはなぜですか。
その理由は、ユニオン内の要素が同じメモリを共有しているためです。
上記のコードは次のように少し変更されています。
union MyUnion
{
int iA;
double dA;
char cA;
};
#include <iostream>
using namespace std;
int main()
{
MyUnion UTestUnion;
UTestUnion.dA = 42.35;
double* dTest = (double*)&(UTestUnion.cA);
cout << *dTest << endl;
return 0;
}
上記のプログラムでは、dTestはUTestUnion.cAのアドレスを指すdouble型のポインターです。アドレスは強制型変換を受けており、元のchar型はdouble型に変換されています。逆参照すると、アドレスに格納されている値が取得されます。
プログラムの出力は42.35です。これは、UTestUnionに割り当てられたdouble要素dAの値です。
ユニオン内の要素が同じメモリを共有しているため、この出力が可能です。UTestUnionのdAには42.35の値が割り当てられ、メモリに格納されます。char型の要素cAも、このメモリの値を表します。ただ、char型とdouble型はコンピュータに異なる方法で格納されるため、cAとdAはどちらもメモリ内で同じ値を表しますが、保存方法が異なるため、その値を直接取得すると動作が異なります。
次の図は、VS2019でプログラムブレークポイントをデバッグした結果
です。図のデバッグ結果から、iAの値が不明であり、cAの値が「?」形式(不明な形式)でエンコードされていることがわかります。 -51。ただし、cAのアドレスがdouble型アドレスに型キャストされた後、dTestの値は通常の42.35になります。これは、dAとcAが同じメモリを共有しているためです。cAのアドレスがdoubleに変更されると、そのアクティブな要素はdAになるため、次のステートメントが使用されます。
(double*)&(UTestUnion.cA);
実際に等しい
&(UTestUnion.dA)
概要
コンソーシアムは非常に興味深いものであり、著者が発見していない機能は間違いなくたくさんあります。誰かがより深い洞察を持っている場合は、ガイダンスのためにメッセージを残してください!