概要
本投稿では、筆者の備忘録として共用体およびビットフィールド構造体についてまとめる。
共用体とは
共用体とは、1つのメモリー領域を確保し、そのメモリー領域内でメンバー(構造体や共用体の中で定義された変数)を扱うデータ型のことである。
共用体で確保するメモリー領域は、その共用体の中で最も大きいメンバーのサイズを確保する。
構造体と似ているが、共用体と構造体の違いについては後の章で解説する。
共用体とビットフィールド
共用体は、ビットフィールド構造体と組み合わせて使用されることがある。
以下に共用体とビットフィールド構造体を組み合わせて使用したサンプルコードとその実行結果を示す。
[サンプルコード (test.c)]
#include <stdio.h>
int main(void){
union {
struct {
unsigned int a: 2;
unsigned int b: 2;
unsigned int c: 4;
}bit;
int all;
}test;
test.bit.a = 1;
test.bit.b = 3;
test.bit.c = 4;
printf("%zu", sizeof(test));
printf("[Byte]\n");
printf("%d\n", test.bit.a);
printf("%d\n", test.bit.b);
printf("%d\n", test.bit.c);
printf("%d\n", test.all);
}
以下に出力結果を示す。
4[Byte]
1
3
4
77
上記の出力結果のように、共用体は下記のように1つのメモリー領域(今回の場合、int型サイズの4[Byte]=32[bit])をメンバー内で共有して使用する。
上記の出力結果を図で表したものが図1である。
共用体と構造体の違い
共用体と構造体の大きな違いはメモリの使い方である。
以下に共用体と構造体を使用したサンプルコードとその実行結果を示す。
[サンプルコード (test.c)]
#include <stdio.h>
int main(void){
struct {
unsigned int a;
unsigned int b;
unsigned int c;
}test;
union {
unsigned int a;
unsigned int b;
unsigned int c;
}test2;
test.a = 1;
test.b = 3;
test.c = 4;
test2.a = 1;
test2.b = 3;
test2.c = 4;
printf("%zu", sizeof(test));
printf("[Byte]\n");
printf("%d\n", test.a);
printf("%d\n", test.b);
printf("%d\n", test.c);
printf("%zu", sizeof(test2));
printf("[Byte]\n");
printf("%d\n", test2.a);
printf("%d\n", test2.b);
printf("%d\n", test2.c);
}
以下に出力結果を示す。
12[Byte]
1
3
4
4[Byte]
4
4
4
上記の出力結果のように、構造体はメンバーごとにメモリー領域を確保している。
構造体のメモリー領域を図で表したものが図2である。
まとめ
本投稿では、共用体およびビットフィールドについてまとめた。
また、補足として、共用体と構造体のメモリー領域確保の違いについてもまとめた。
以下にポイントをまとめる。
- 共用体とは、1つのメモリー領域を確保し、そのメモリー領域内でメンバー(構造体や共用体の中で定義された変数)を扱うデータ型のことである。
- 共用体で確保するメモリー領域は、その共用体の中で最も大きいメンバーのサイズを確保する。
- 構造体は、共用体とは異なり、構造体内のメンバーごとにメモリー領域を確保する。