ユニオン構造

場合によっては、さまざまな場面でさまざまなデータ型を表すためにデータ構造が必要になることがあります。たとえば、果物の「量」を表すために 1 つのデータ構造のみを使用する場合、この構造は整数 (リンゴ 6 個) である必要があり、場合によっては浮動小数点数 (イチゴ 1.5 キログラム) である必要があります。

C言語には、柔軟に変更できるデータ構造をカスタマイズするためのUnion構造が用意されています。内部にはさまざまな属性が含まれていますが、すべての属性がメモリを共有しているため、これらの属性は同じバイナリ データを解釈し、多くの場合、1 つの属性の解釈のみが意味を持ちます。さらに、後で書き込まれた属性は以前の属性を上書きします。つまり、同じメモリが最初に 1 つの属性で使用され、次に別の属性で使用される可能性があります。これを行う最大の利点は、メモリ領域を節約できることです。

結合数量 {
  短いカウント。
  フロートウェイト。
  フロートボリューム;
};

上の例では、union コマンドは 3 つのプロパティを含むデータ型 quantity を定義します。 3 つの属性が含まれていますが、書き込むことができる値は 1 つだけです。3 つの属性は、この値の異なる解釈になります。多くの場合、最後に割り当てられた属性は、意味のある値を取得できる属性です。

使用する場合は、この型の変数を宣言します。

//書き方その1
結合量 q;
q.カウント = 4;

//書き方2
結合数量 q = {.count=4};

//書き方3
結合量 q = {4};

上記のコードは、Union 構造体に値を割り当てる 3 つの方法を示しています。最後の書き方では属性名を指定せず、最初の属性に値が代入されます。

上記のコードを実行すると、q.count は値を取得できますが、他の 2 つの属性は値を取得できません。

printf("カウントは %i\n", q.count); // カウントは 4
printf("weight is %f\n", q.weight); // 未定義の動作

q.weight 属性に値を指定したい場合は、まずそれに値を割り当てる必要があります。

q.weight = 0.5;
printf("weight is %f\n", q.weight); // 重みは 0.5

他の属性に値が割り当てられると、本来値を取得できる q.count 属性が変更されてしまい、使用する意味がなくなる可能性があります。これを除けば、Union 構造体の他の用途は基本的に Struct 構造体と同じです。

Union 構造体はポインタ演算子 -> もサポートしています。

結合数量 {
  短いカウント。
  フロートウェイト。
  フロートボリューム;
};

結合量 q;
q.カウント = 4;

結合数量* ptr;
ptr = &q;

printf("%d\n", ptr->count); // 4

上の例では、ptrq のポインタであり、ptr->countq.count と同等です。

Union 構造体ポインタは、データが現在解釈されている属性に応じて、対応するデータ型になります。

ユニオンフー{
  int a;
  フロート b;
}x;

int* foo_int_p = (int *)&x;
float* foo_float_p = (float *)&x;

x.a = 12;
printf("%d\n", x.a); // 12
printf("%d\n", *foo_int_p); // 12

x.b = 3.141592;
printf("%f\n", x.b); // 3.141592
printf("%f\n", *foo_float_p); // 3.141592

上の例では、「&x」は foo 構造体へのポインタであり、そのデータ型は現在割り当てられている属性によって完全に決定されます。

typedef コマンドは、Union データ型の別名を指定できます。

typedef 共用体 {
  短いカウント。
  フロートウェイト。
  フロートボリューム;
} 量;

上の例では、union コマンドは 3 つの属性を含むデータ型を定義し、typedef コマンドはそれを quantity としてエイリアスします。

ユニオン構造の主な利点は省スペースです。メモリ空間のセクションをさまざまなタイプのデータに再利用します。 3 つの属性が定義されていますが、同時に使用できるのは 1 つだけです。Union 構造を使用すると、他の 2 つの属性のスペースを節約できます。 Union 構造体が占有するメモリ長は、その最長の内部属性の長さと同じです。


作者: wangdoc

アドレス: https://wangdoc.com/

ライセンス: クリエイティブ・コモンズ 3.0