連合 同じメモリ位置にある異なるデータ型の異なる変数のコレクションであるユーザー定義データ型として定義できます。共用体は多数のメンバーとして定義することもできますが、特定の時点で値を含めることができるメンバーは 1 つだけです。
NFAからDFAへ
Union はユーザー定義のデータ型ですが、構造体とは異なり、同じメモリ位置を共有します。
例を通してこれを理解しましょう。
struct abc { int a; char b; }
上記のコードは、2 つのメンバー、つまり型の 'a' で構成されるユーザー定義の構造体です。 整数 およびタイプの「b」 キャラクター 。 「a」と「b」のアドレスを確認すると、アドレスが異なることがわかりました。したがって、構造内のメンバーは同じメモリ位置を共有していないと結論付けます。
共用体を定義すると、共用体は構造体の定義と同じ方法で定義されることがわかりましたが、違いは、union キーワードが共用体のデータ型の定義に使用されるのに対し、struct キーワードは構造体の定義に使用されることです。共用体にはデータ メンバー (つまり、「a」と「b」) が含まれています。両方の変数のアドレスをチェックすると、両方のアドレスが同じであることがわかりました。これは、共用体のメンバーが同じメモリ位置を共有することを意味します。
メモリ割り当てを図で表したものを見てみましょう。
下の図は、構造を図で表したものです。この構造体には 2 つのメンバーがあります。つまり、1 つは整数型で、もう 1 つは文字型です。 1 ブロックは 1 バイトに等しいため、したがって、「a」変数には 4 つのメモリ ブロックが割り当てられ、「b」変数には 1 つのメモリ ブロックが割り当てられます。
以下の図は、組合員のイメージを示しています。両方の変数は同じメモリ位置を共有し、同じ初期アドレスを持ちます。
Union では、メンバーはメモリの場所を共有します。いずれかのメンバーに変更を加えようとすると、他のメンバーにも変更が反映されます。例を通してこの概念を理解してみましょう。
union abc { int a; char b; }var; int main() { var.a = 66; printf(' a = %d', var.a); printf(' b = %d', var.b); }
上記のコードでは、union には 2 つのメンバー、つまり 'a' と 'b' があります。 「var」はunion abc型の変数です。の中に 主要() このメソッドでは、「a」変数に 66 を代入するので、var.a は画面に 66 を表示します。 「a」と「b」は両方ともメモリ位置を共有しているため、 変数b 'を印刷します B ' (ASCII コード 66)。
組合の規模を決める
ユニオンのサイズは、ユニオンの最大メンバーのサイズに基づきます。
例を通して理解しましょう。
union abc{ int a; char b; float c; double d; }; int main() { printf('Size of union abc is %d', sizeof(union abc)); return 0; }
ご存知のとおり、int のサイズは 4 バイト、char のサイズは 1 バイト、float のサイズは 4 バイト、double のサイズは 8 バイトです。 double 変数は 4 つの変数の中で最も多くのメモリを占有するため、合計 8 バイトがメモリに割り当てられます。したがって、上記のプログラムの出力は 8 バイトになります。
ポインタを使用した共用体のメンバーへのアクセス
(->) 矢印演算子を使用すると、ポインターを介して共用体のメンバーにアクセスできます。
例を通して理解しましょう。
#include union abc { int a; char b; }; int main() { union abc *ptr; // pointer variable declaration union abc var; var.a= 90; ptr = &var; printf('The value of a is : %d', ptr->a); return 0; }
上記のコードでは、var 変数のアドレスを格納するポインター変数、つまり *ptr を作成しました。これで、ptr は (->) 演算子を使用して変数 'a' にアクセスできるようになります。したがって、上記のコードの出力は 90 になります。
なぜ C 共用体が必要なのでしょうか?
C 共用体の必要性を理解するために、1 つの例を考えてみましょう。次の 2 つのアイテムがあるストアを考えてみましょう。
- 本
- シャツ
店舗オーナーは、上記 2 つの項目の記録を関連情報とともに保存したいと考えています。たとえば、書籍にはタイトル、著者、ページ数、価格が含まれ、シャツには色、デザイン、サイズ、価格が含まれます。 「価格」プロパティは両方の項目に共通です。ストアの所有者はプロパティを保存し、次にレコードをどのように保存するかを考えています。
当初、彼らは以下に示すような構造でレコードを保存することにしました。
struct store { double price; char *title; char *author; int number_pages; int color; int size; char *design; };
上記の構造は、店主が保管したいすべてのアイテムで構成されています。上記の構造は完全に使用可能ですが、価格は両方のアイテムの共有財産であり、残りのアイテムは個別です。価格、*タイトル、*著者、およびnumber_pagesなどのプロパティは書籍に属し、色、サイズ、*デザインはシャツに属します。
構造体のメンバーにアクセスする方法を見てみましょう 。
int main() { struct store book; book.title = 'C programming'; book.author = 'Paulo Cohelo'; book.number_pages = 190; book.price = 205; printf('Size is : %ld bytes', sizeof(book)); return 0; }
上記のコードでは、次のタイプの変数を作成しました。 店 。タイトル、著者、ページ数、価格の変数に値を割り当てましたが、book 変数にはサイズ、色、デザインなどのプロパティがありません。したがって、メモリの無駄遣いになります。上記の構造体のサイズは 44 バイトになります。
ユニオンを使用すると、スペースを大幅に節約できます。
#include struct store { double price; union { struct{ char *title; char *author; int number_pages; } book; struct { int color; int size; char *design; } shirt; }item; }; int main() { struct store s; s.item.book.title = 'C programming'; s.item.book.author = 'John'; s.item.book.number_pages = 189; printf('Size is %ld', sizeof(s)); return 0; }
上記のコードでは、store 型の変数を作成しました。上記のコードでは共用体を使用しているため、変数によって占有される最大のメモリがメモリ割り当ての対象として考慮されます。上記のプログラムの出力は 32 バイトです。構造体の場合は 44 バイトが得られ、共用体の場合は 44 バイトが得られます。したがって、44 バイトは 32 バイトより大きく、多くのメモリ領域を節約できます。