共用体

共用体とは

C言語には、構造体と非常に似ている共用体(きょうようたい)という概念があります。ひとつのメモリ領域に複数の変数を割り当てることができるという意味では、構造体と同じですが、使われ方が根本的に違います。

サンプルプログラム

では実際に、共用体を使ったプログラムを見て見ましょう。以下のサンプルを実行してみてください。

listex5-union-1:main.c
#include <stdio.h>
#include <string.h>

union data{
	int n;		//	整数のデータ
	double d;	//	実数のデータ
	char s[16];	//	文字列のデータ	
};

void main(){
	union data d[3];
	d[0].n =  1;
	d[1].d = 3.14;
	strcpy(d[2].s,"Hello");
	printf("%d %f %s\n",d[0].n,d[1].d,d[2].s);
}
実行結果
1 3.140000 Hello

プログラム4行目から8行目で、共用体の定義をしています。共用体の定義の仕方は、構造体とよく似ており、以下のとおりになります。

共用体の定義
union (共用体名){
    データ型 メンバー名;
・・・・
};

構造体同様、共用体では、複数のメンバーを定義できます。unionが、共用体を表すキーワードであり、そのあとが名前になります。最後は;(セミコロン)で終了します。

このように、定義の仕方が構造体に非常によく似ている共用体ですが、使い方もよく似ています。11行目のように

共用体変数の定義
union student data;

とすると、dataという名前共用体変数を定義できます。12行目から14行目を見ればわかるとおり、メンバーへのアクセス方法は、構造体と同じです。

共用体と構造体の違い

では、共用体と構造体は、どこが違うのでしょうか?その答えは、構造体はすべてのメンバーに対して、同時に別々の値を代入することができるのに対して、共用体は、一つの変数に対し、どれか一つのメンバーしか同時に使えないという点にあります。

たとえば、12行目では、共用体変数d[0]の整数型メンバnに対して値を代入していますが、この場合、d[0]は、d,sといったパラメータは使いません。d[1]、d[2]も同様で、それぞれ、d,文字列sのみを使うことになります。

つまり、複数あるメンバーのうち、同時に使うことができるのはどれか一つ、ということになるわけです。

そのため、共用体のメモリサイズは、メンバーの中のもっとも大きいものと等しくなっています。この場合だと、文字列配列のsのサイズが、この共用体一つの大きさになります。

共用体を使うメリット

では、なぜこのような共用体を使うのでしょうか?理由は、メモリの節約です。たとえば、複数のデータ型を取る可能性のデータを、一つの配列にまとめたいとき、共用体を用いると管理が楽になるうえに、メモリが節約できます。

もし同じことを構造体でやろうとすると、使っていないメンバーの分のメモリが浪費されるので効率的ではありません。