共用体

  • すべてのフィールドが互いに重なっており、一度に使うことができるのは1つのフィールドしかない。
  • 同じ領域を使用することを利用して、あるフィールドで書いて別のフィールドで読み出すことで、データのビットパターンを調べたり、ビット操作をするという処理依存な特殊な使い方をすることができる。
  • 文字通りメモリ領域を共用するので、メモリを節約できる。

共用体と構造体の違い

  • 構造体
    • 構造体1つの大きさは「各メンバの大きさの総和+パディングされた大きさ」になる。
    • つまり、各メンバのアドレスの先頭アドレスは異なる。
  • 共用体
    • 共用体1つの大きさは各メンバのうちの最大値になる。
    • 各メンバのアドレスの先頭アドレスが一致するか、最後のアドレスが一致するかは処理系依存である。
      • いずれにせよすべてのメンバは重なっている。

 次に構造体と共用体を比較できるプログラムを示す。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 
 
-
|
|
!
 
-
|
|
!
 
-
|
|
|
|
|
|
|
|
|
|
!
#include <stdio.h>
 
typedef struct status1_tag{
    long code;
    char age;
}status1;
 
typedef union status2_tag{
    long code;
    char age;
}status2;
 
int main(void){
    status1 personal1;
    status2 personal2;
 
    printf("構造体の大きさ:%d\n", sizeof(status1));
    printf("codeのアドレス:%p\n",&personal1.code);
    printf("ageのアドレス :%p\n\n",&personal1.age);
 
    printf("共用体の大きさ:%d\n", sizeof(status2));
    printf("codeのアドレス:%p\n",&personal2.code);
    printf("ageのアドレス :%p\n\n",&personal2.age);
}

 このプログラムの実行結果は次の通りである。

構造体の大きさ:8
codeのアドレス:0012FF6C
ageのアドレス :0012FF70

共用体の大きさ:4
codeのアドレス:0012FF68
ageのアドレス :0012FF68

 私の環境(Intel Pentium4+MS VC++)では共用体の各メンバは先頭アドレスが揃えて重なっていることがわかる。