struct
との違いを示す良い例はありますか? 基本的に、はメンバーのすべてのメモリを使用し、最大のメンバーのメモリ領域を使用するunion
ことはわかっています。 他に OS レベルの違いはありますか?struct
union
ベストアンサー1
ユニオンでは、すべての要素が同じ場所に格納されるため、要素の 1 つだけを使用することになります。これは、複数の型のいずれかになる可能性のあるものを格納したい場合に便利です。一方、構造体では、各要素ごとに個別のメモリ位置があり、それらすべてを一度に使用できます。
具体的な使用例を挙げると、私は少し前に Scheme インタープリタに取り組んでいて、基本的に Scheme データ型を C データ型にオーバーレイしていました。これには、値の型を示す列挙型とその値を格納する共用体を構造体に格納することが含まれていました。
union foo {
int a; // can't use both a and b at once
char b;
} foo;
struct bar {
int a; // can use both a and b simultaneously
char b;
} bar;
union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!
struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK
編集: xb を 'c' に設定すると xa の値がどうなるか疑問に思っている場合、技術的に言えば未定義です。ほとんどの最新のマシンでは、char は 1 バイト、int は 4 バイトなので、xb に値 'c' を設定すると、xa の最初のバイトにも同じ値が適用されます。
union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
プリント
99, 99
なぜ 2 つの値が同じなのでしょうか? int 3 の最後の 3 バイトがすべてゼロなので、99 として読み取られます。xa にもっと大きな数値を入力すると、必ずしもそうではないことがわかります。
union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
プリント
387427, 99
実際のメモリ値を詳しく確認するには、値を 16 進数で設定して出力してみましょう。
union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);
プリント
deadbe22, 22
0x22 が 0xEF を上書きした場所がはっきりとわかります。
しかし
C では、int 内のバイトの順序は定義されていません。このプログラムは、私の Mac では 0xEF を 0x22 で上書きしましたが、int を構成するバイトの順序が逆になっているため、代わりに 0xDE を上書きするプラットフォームもあります。したがって、プログラムを作成するときは、共用体内の特定のデータを上書きする動作に決して依存しないでください。これは移植性がないからです。
バイトの順序付けの詳細については、以下を参照してください。エンディアン。