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

C言語のユニオンへのポインタをわかりやすく解説!宣言方法からアクセス方法まで

C言語におけるユニオン(union)とは、異なるデータ型の複数の変数が同じメモリ領域を共有する仕組みです。構造体(struct)と似ていますが、すべてのメンバーがメモリを占有する構造体とは異なり、ユニオンでは一度に1つのメンバーしか値を保持できません。

この記事では、ユニオンへのポインタの使い方について、基本構文から実践的なサンプルコードまで詳しく解説します。

ユニオンへのポインタの基本構文

C言語でユニオンを定義する際の基本的な構文は以下のとおりです。

union uniontag{
    datatype member1;
    datatype member2;
    ----
    ----
    datatype member n;
};

ユニオンの定義例

次の例は、int型・float型・char型の3つのメンバーを持つユニオンの定義です。

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;

この方法では無名ユニオン(unions without tag)となり、この宣言以降に同じ型の変数を新たに作成することはできません。

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

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

ユニオンを使う上での重要なポイント

  • ユニオンが宣言されると、コンパイラは自動的に最もサイズの大きいメンバーと同じ大きさのメモリ領域を確保します。
  • 任意の時点で参照できるのは1つのメンバーだけです。最後に代入した値以外は正しく読み取れない場合があります。
  • メンバーへのアクセス方法は、構造体と同じ構文を使用します。
  • 通常の変数からメンバーにアクセスする場合はドット演算子(.)を使用します。
  • ポインタ経由でメンバーにアクセスする場合はアロー演算子(->)を使用します。

ポインタによるユニオンメンバーへのアクセス

構造体と同様に、ユニオンへのポインタを作成し、アロー演算子(->)を使ってメンバーにアクセスすることができます。

サンプルプログラム1

次のプログラムは、C言語におけるユニオンへのポインタの使用例です。

#include <stdio.h>
union pointer {
    int num;
    char a;
};
int main(){
    union pointer p1;
    p1.num = 75;
    // p2はユニオンp1へのポインタ
    union pointer* p2 = &p1;
    // ポインタを使ってユニオンのメンバーにアクセス
    printf("%d %c", p2->num, p2->a);
    return 0;
}

実行結果

75 K

このプログラムでは、まずp1.numに75を代入しています。その後、p1のアドレスをポインタp2に格納し、p2->numとp2->aでメンバーにアクセスしています。75はASCIIコードで文字「K」に対応するため、このような出力になります。

サンプルプログラム2

同じプログラムで入力値を変更した例を見てみましょう。

#include <stdio.h>
union pointer {
    int num;
    char a;
};
int main(){
    union pointer p1;
    p1.num = 90;
    // p2はユニオンp1へのポインタ
    union pointer* p2 = &p1;
    // ポインタを使ってユニオンのメンバーにアクセス
    printf("%d %c", p2->num, p2->a);
    return 0;
}

実行結果

90 Z

90はASCIIコードで文字「Z」に対応しているため、「90 Z」と出力されます。このように、ユニオンでは同じメモリ領域を異なるデータ型として解釈できることが確認できます。

まとめ

ユニオンへのポインタは、構造体へのポインタとほぼ同じ要領で扱うことができます。ポイントは以下の2つです。

  • ポインタの宣言は「union タグ名* ポインタ変数名;」の形式で行う
  • メンバーへのアクセスはアロー演算子(->)を使用する

メモリを効率的に使いたい場面や、同じデータを異なる型として扱いたい場面でユニオンは非常に有用です。ぜひ実際にコードを書いて動作を確認してみてください。

  1. C言語におけるユニオンとポインタの使い方を徹底解説

    ユニオン(共用体)とは、異なるデータ型を持つ複数の変数が、同一のメモリ領域を共有するための仕組みです。構造体が各メンバーごとに独立したメモリを割り当てるのに対し、ユニオンではすべてのメンバーが同じアドレスを参照するという点が大きな特徴です。 ユニオンの構文 ユニオンを定義するときの基本的な書式は次の通りです。 union タグ名{ データ型 メンバー1; データ型 メンバー2; ---- ---- データ型 メンバーn; }; 実際の記述例を見てみましょう。 union sample{ int a; float b; char

  2. C言語のポインタ入門!宣言・初期化から配列アクセスの実例まで徹底解説

    ポインタ(pointer)とは、他の変数のメモリアドレスを格納するための変数です。C言語においてポインタは、メモリを直接操作したり、関数間でデータを効率的にやり取りしたりするために欠かせない重要な概念です。 ポインタの宣言・初期化とアクセス まず、次のような通常の整数変数の宣言を見てみましょう。 int qty = 179; 変数qtyには値「179」が格納されると同時に、メモリ上のどこかにその格納場所(アドレス)が割り当てられます。 ポインタの宣言 int *p; 「p」はポインタ変数であり、別の整数型(int)変数のアドレスを保持します。変数名の前にアスタリスク(*)を付けることで、「こ