Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C言語の共用体(union)とは?構文・宣言方法・使い方をわかりやすく解説

共用体(union)とは

C言語における共用体(union)とは、異なるデータ型を持つ複数の変数が、同一のメモリ領域を共有するための仕組みです。構造体(struct)が各メンバに個別のメモリを割り当てるのに対し、共用体ではすべてのメンバが同じメモリを参照するため、メモリの節約に役立ちます。

共用体の構文

共用体を定義する基本的な構文は以下のとおりです。

union タグ名{
    データ型 メンバ1;
    データ型 メンバ2;
    ----
    ----
    データ型 メンバn;
};

定義例

次の例では、int型・float型・char型の3つのメンバを持つ「sample」という名前の共用体を定義しています。

union sample{
    int a;
    float b;
    char c;
};

共用体変数の宣言方法

共用体変数の宣言には、主に以下の3つの方法があります。

方法1:定義と同時に変数を宣言する

union sample{
    int a;
    float b;
    char c;
}s;

方法2:タグ名なしで変数を宣言する

union{
    int a;
    float b;
    char c;
}s;

方法3:定義後に別途変数を宣言する

union sample{
    int a;
    float b;
    char c;
};
union sample s;

共用体を使う際の注意点

  • 共用体が宣言されると、コンパイラは自動的に最もサイズの大きいメンバに対応したメモリ領域を確保します。

  • 任意の時点で値を保持できるのは1つのメンバだけです。新しいメンバに値を代入すると、それまでのメンバの値は失われます。

メンバへのアクセス方法

  • メンバへのアクセスには、構造体と同じ構文を使用します。

  • 通常の変数の場合はドット演算子(.)を使ってメンバにアクセスします。

  • ポインタ経由でアクセスする場合はアロー演算子(->)を使用します。

サンプルプログラム1

次のプログラムは、共用体の基本的な使い方を示したものです。

#include <stdio.h>

union sample{
    int a;
    float b;
    char c;
};

main( ){
    union sample s = {10, 20.5, 'A'};
    printf("a=%d\n", s.a);
    printf("b=%f\n", s.b);
    printf("c=%c\n", s.c);
}

実行結果

上記のプログラムを実行すると、次のような出力が得られます。

a = garbage value
b = garbage value
c = A

このように、初期化子リストで複数のメンバに値を指定しても、正しく反映されるのは最初のメンバのみです。これは、すべてのメンバが同じメモリ領域を共有しており、後に代入した値が前の値を上書きしてしまうためです。共用体では、必要なタイミングで1つずつメンバに値を代入するのが一般的な使い方です。

構造体の共用体(ネスト)

  • 共用体の中に構造体を入れ子にすることができ、これを「構造体の共用体」と呼びます。

  • 逆に、構造体の中に共用体を定義することも可能です。

サンプルプログラム2

次のプログラムは、共用体内に構造体を組み込んだ使用例です。

#include <stdio.h>

struct x{
    int a;
    float b;
};

union z{
    struct x s;
};

main( ){
    union z u;
    u.s.a = 10;
    u.s.b = 30.5;
    printf("a=%d\n", u.s.a);
    printf("b=%f\n", u.s.b);
}

実行結果

上記のプログラムを実行すると、次のような出力が得られます。

a= 10
b = 30.5

この例では、共用体zの中に構造体xを含めています。ドット演算子を連続して使うことで、「u.s.a」のように入れ子になったメンバへアクセスできます。構造体xのメンバaとbはそれぞれ独立したメモリを持つため、両方の値が正しく保持される点に注目してください。

まとめ

共用体は、異なるデータ型の変数が同じメモリを共有することでメモリ使用量を抑えられる便利な機能です。ただし、同時に1つのメンバしか有効な値を保持できない点には注意が必要です。構造体と組み合わせることで、より柔軟なデータ構造を設計できるようになります。

  1. C言語のstrcmp()関数とは?文字列比較の基本と使い方を徹底解説

    C言語の標準ライブラリ関数 int strcmp(const char *str1, const char *str2) は、ポインタ str1 が指し示す文字列と、str2 が指し示す文字列を比較するための関数です。C言語において、文字型の配列は「文字列」と呼ばれます。まずは文字列の基本的な扱い方から確認していきましょう。文字列の宣言文字列(文字配列)の宣言は以下のように行います。char stringname [size];例えば、char string[50]; と宣言すれば、最大50文字の長さを持つ文字列を格納できます。文字列の初期化文字列の初期化には、主に次の2つの方法があります。1

  2. C#の構造体(struct)とは?特徴と定義方法をわかりやすく解説

    C#における構造体(struct)は、値型に分類されるデータ型です。1つの変数の中に、文字列や数値など異なるデータ型の関連データをまとめて格納できるのが大きな特徴です。構造体を作成する際には、structキーワードを使用します。C#の構造体の主な特徴メソッド、フィールド、インデクサー、プロパティ、演算子メソッド、イベントを持つことができます。コンストラクターを定義できますが、デストラクターは定義できません。また、引数なしの既定のコンストラクターは自動的に定義されるため、開発者が独自に定義することはできません。クラスと異なり、他の構造体やクラスを継承することはできません。他の構造体やクラスの基底