Project_OKI’s diary

エンジニアの勉強ブログ

C言語基礎知識38(union(共用体)について)

union (共用体)について

この記事では、C言語におけるunionの内容と使用方法について記載する。

 

1. 目的

 ・unionの意味ついて知る。

 ・union使い方を知る。

 

目次

 

2. union(共用体)とは

 ・同じメモリ領域を複数のメンバが共有するデータ型の一つ

   (各々の要素は、名前が付けられ、メンバと呼ぶ)

 ・同じメモリ領域を使用し、様々な種類のデータを入れる場合に使う。
 ・同じ場所にデータを格納する以外は、構造体に似ている。

 ・メモリが節約できるメリットがある。

 

 参考:

 ・union

 ・C言語 共用体 union【メモリをシェアする考え方と使い方】

 ・【C言語入門】union(共用体)の使い方 | 侍エンジニアブログ

 

3. unionの使い方

 ・使用方法:

 (1) union(共用体)の作成
typedef union {
    データ型 メンバ名1;
    データ型 メンバ名2;
    データ型 メンバ名3;
    ・・・ ・・・;
}共用体名;

 例:

typedef union{ 
char c_unum;
int i_unum;
}UNIONA;
 (2) union(共用体)の宣言
共用体名(型) 共用体変数;
共用体変数.メンバ名 = xx;

例:

    UNIONA uni;     ///< 共用体の宣言

 

※使い方としては基本的に構造体と一緒

 ここではtypedefを使用しているがtypedefを使用しない方法もある。

 下記構造体の記事を参照

 →組み込みC言語基礎知識7(構造体1) - Project_OKI’s diary

 

3. プログラム作成(共用体のサイズ確認)

 (1 )共用体と構造体を作成し、それぞれのサイズを確認する。

#include <stdio.h>
///共用体の作成
typedef union{
    char c_unum;
    int  i_unum;
}UNIONA;

///構造体の作成
typedef struct{
    char c_snum;
    int  i_snum;
}STRUCTA;

int main(void){
    /// 宣言
    UNIONA uni;     ///< 共用体の宣言
    STRUCTA st;     ///< 構造体の宣言

    ///サイズ確認
    printf("uni_size=%lu\n",sizeof(uni));           ///共用体のサイズ
    printf("uni.c_unum_size=%lu\n",sizeof(uni.c_unum));    ///共用体のサイズ
    printf("uni.i_unum_size=%lu\n",sizeof(uni.i_unum));    ///共用体のサイズ

    printf("st_size=%lu\n",sizeof(st));      /// 構造体のサイズ
    printf("st.c_snum_size=%lu\n",sizeof(st.c_snum));      /// 構造体のサイズ
    printf("st.i_snum_size=%lu\n",sizeof(st.i_snum));      /// 構造体のサイズ
}

実行結果:https://paiza.io/projects/EbWIRmC40l9akrxXnRTNLQ

 

 ・uniは、サイズが4、stはサイズが8となる。

 ・共用体のuniは、int とcharが同じメモリ領域を使用する為、

  intとcharのサイズの最小値となる。

 ・構造体は、intとcharの宣言した分増えていく。

 

 (2 )共用体と構造体を作成し、それぞれのサイズを確認する。(数増加)

#include <stdio.h>
///共用体の作成
typedef union{
    char c_unum;
    int  i_unum;
    int  i_unum2;
    int  i_unum3;
    int  i_unum4;
}UNIONA;

///構造体の作成
typedef struct{
    char c_snum;
    int  i_snum;
    int  i_snum2;
    int  i_snum3;
    int  i_snum4;
}STRUCTA;

int main(void){
    /// 宣言
    UNIONA uni;     ///< 共用体の宣言
    STRUCTA st;     ///< 構造体の宣言

    ///サイズ確認
    printf("uni_size=%lu\n",sizeof(uni));   ///< 共用体のサイズ
    printf("st_size=%lu\n",sizeof(st));     ///< 構造体のサイズ
}

実行結果:https://paiza.io/projects/Q5haSqZta64MdGwYKFRyKQ?language=c

 ・上記の場合でも共用体のサイズは4となる。

 ・それに対し構造体のサイズは20となる。

 

3. プログラム作成(共用体の使用:値の代入)

  (1)共用体に値を代入

#include <stdio.h>
///共用体の作成
typedef union{
    short c_unum;
    int  i_unum;
}UNIONA;

int main(void){
    /// 宣言
    UNIONA uni;     ///< 共用体の宣言

    uni.c_unum = 1;
    printf("uni_size=%d\n",uni.c_unum);   ///< 共用体のサイズ
    printf("uni_size=%d\n",uni.i_unum);   ///< 共用体のサイズ
    uni.i_unum = 2;
    printf("uni_size=%d\n",uni.c_unum);   ///< 共用体のサイズ
    printf("uni_size=%d\n",uni.i_unum);   ///< 共用体のサイズ
}

実行結果:https://paiza.io/projects/lysUnWQ2M82Fcy0Zpl_BCQ?language=c

 

 ・メモリを共有している為、uni.c_unumに1を入れると、uni.i_unumも同じ値となる。

 ・uni.i_unumに2を入れるとuni.c_unumも同じ値となる。

 

3. プログラム作成(共用体の使用:構造体のメモリ削減)

 (1)共用体を使用した構造体使用時のメモリ削減

#include <stdio.h>
///構造体の作成
typedef struct{
    int test1;
    int test2;
}TEST;

typedef struct{
    int point1;
    int point2;
    int point3;
}POINT;

typedef struct{
    int oder1;
    int oder2;
}ODER;

///共用体の作成
typedef union{
    TEST tes;
    POINT poi;
    ODER ode;
}UNIONA;

int main(void){
    /// 宣言
    UNIONA uni;     ///< 共用体の宣言
    /// 共用体のサイズ確認
    printf("uni_size=%lu\n",sizeof(uni));
    /// 構造体のサイズ確認
    printf("uni.tes_size=%lu\n",sizeof(uni.tes));
    printf("uni.poi_size=%lu\n",sizeof(uni.poi));
    printf("uni.ode_size=%lu\n",sizeof(uni.ode));

    uni.tes.test1 = 1;      ///< 構造体tes.test1に1を代入
    printf("test1=%d\n",uni.tes.test1);
    uni.poi.point1 = 2;     ///< 構造体poi.point1に2を代入
    printf("test1=%d\n",uni.tes.test1);
    printf("test1=%d\n",uni.poi.point1);
}

実行結果:https://paiza.io/projects/83sL9xvUuXzmCd7hgSrriQ?language=c

 

 (a) 通常、構造体TEST、POINT、ODERを使用したい場合、

  それぞれ構造体を宣言する。

  その場合、使用メモリは、28byteになる。

  しかし、この構造体(TEST、POINT、ODER)を同時に使わないので、

  メモリを省略したい場合がある。

  その時、上記のようにunionを使用することで、

  12byteで3つの構造体を使用することが可能となる。

 

 構造体の関連記事:

 ・C言語基礎知識7(構造体1) - Project_OKI’s diary

 ・C言語基礎知識17(構造体とポインタとアロー演算子の使い方) - Project_OKI’s diary

 ・C言語基礎知識26(構造体の配列) - Project_OKI’s diary

 ・C言語基礎知識27(構造体を複数の別ファイルで使用する) - Project_OKI’s diary

 ・C言語基礎知識28(構造体の中で構造体を宣言する) - Project_OKI’s diary

 ※基本的な使い方は構造体と同じ為、他の使い方については構造体の記事を参照

 

 

組み込みC言語