ストラクチャーとユニオンの違い

構造体 "と "ユニオン "の違いを示す良い例はありますか? 基本的には、structはそのメンバーのすべてのメモリを使用し、unionは最大のメンバーのメモリスペースを使用するということを知っています。他にOSレベルでの違いはありますか?

ソリューション

ユニオンでは、すべての要素が同じ場所に格納されているため、いずれかの要素だけを使用することになります。そのため、複数の型になる可能性があるものを格納したい場合に便利です。一方、構造体は、要素ごとに独立したメモリの場所を持ち、すべての要素を一度に使用することができます。

具体的な使用例を挙げると、私は少し前にSchemeのインタープリタを作っていて、C言語のデータ型の上にSchemeのデータ型を重ねていました。これは、構造体に値の型を示すenumと、その値を格納するunionを格納するというものだ。

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

編集: x.bを 'c'に設定するとx.aの値が何に変わるのか気になるところですが、技術的には未定義です。最近のマシンでは、charは1バイト、intは4バイトなので、x.bに 'c'という値を与えると、x.aの第1バイトにも同じ値が与えられます。

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

プリント

99, 99

なぜこの2つの値は同じなのでしょうか?int 3の最後の3バイトはすべて0なので、99とも読めるからです。x.aにもっと大きな数字を入れると、必ずしもそうではないことがわかります。

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を上書きしているのがよくわかります。

BUT

このプログラムは、私のMacでは0xEFを0x22に上書きしましたが、他のプラットフォームではintを構成するバイトの順序が逆なので、代わりに0xDEに上書きされてしまうことがあります。したがって、プログラムを作成する際には、ユニオン内の特定のデータを上書きするという動作は、ポータブルではないので、決して当てにしてはいけません。

バイトの順序についての詳しい読み物は、endiannessをご覧ください。

解説 (12)

"union"と"struct"は、C言語の構造体です。どちらかのキーワードを使用した場合に異なるコードを生成するのはコンパイラなので、両者の違いをOSレベルで語るのは不適切です。

解説 (0)

構造体では、その中のすべての要素の合計サイズが割り当てられます。

ユニオンは、最大のメンバーが必要とする量のメモリを割り当てます。

解説 (1)