共用体


一つの記憶領域を確保して、そこに色々なデータ型のデータを格納できる機能を持つ共用体(union)と呼ばれるデータ型があります。
union 共用体タグ{
  共用体メンバ;
  ...
} 共用体変数; 
のような形になります。
しかし、記憶できるの一つのメンバだけです。あとで別なメンバに値を代入すると、前のメンバの値は無効になります。また、共用体は初期化できません。

ソースコード

源文件
  1|/* union01.c */                                                                       
  2|
  3|#include <stdio.h>
  4|
  5|union myunion{
  6|  int i;
  7|  double d;
  8|  char c;
  9|  char *str;
 10|};
 11|
 12|int main(void){
 13|  union myunion u;
 14|
 15|  u.i = 200;
 16|  printf("u.i = %d\n", u.i);
 17|
 18|  u.d = 92.25;
 19|  printf("u.d = %f\n", u.d);
 20|
 21|  u.c = 'A';
 22|  printf("u.c = %c\n", u.c);
 23|
 24|  u.str = "ABCDE";
 25|  printf("u.str = %s\n", u.str);
 26|
 27|  return 0;                                                                           
 28|}

実行結果

u.i = 200
u.d = 92.250000
u.c = A
u.str = ABCDE

共用体では、現在どの型が格納されているのかに注意を払わなくてはなりません。また、18行目「u.d = 95.25」を実行した後で u.i を表示するようなプログラムを書いてはいけません。



太郎君の学校の体育大会では、生徒は「100メータル競争」か「パン食い競走」のいずれかに出場しなくてはなりません。生徒名と、出場した競技名、成績をメンバする構造体を考えてみましょう。100メートル競争ではタイムが、パン食い競走では順位が成績として記録されることにします。

ソースコード

源文件
  1|/* union02.c */
  2|
  3|#include <stdio.h>
  4|#include <stdlib.h>
  5|#include <string.h>                                                                                                                                                           
  6|
  7|#define PAN "パン食い競走"
  8|#define KYO "100m 競走"
  9|#define NO 6
 10|
 11|typedef struct {
 12|  char name [16];
 13|  char kyogi[32];
 14|  union {
 15|    double tm;
 16|    int juni;
 17|  } seiseki;
 18|} DATA, *LPDATA;
 19|
 20|int myinput (LPDATA p, char *nm, char *kg, char *sk);
 21|
 22|int main(void){
 23|  DATA data[NO];
 24|  LPDATA lpdata;
 25|  int i;
 26|
 27|  lpdata = data;
 28|
 29|  myinput(lpdata + 0, "田中", PAN, "1");
 30|  myinput(lpdata + 1, "佐藤", KYO, "20.5");
 31|  myinput(lpdata + 2, "河野", PAN, "2");
 32|  myinput(lpdata + 3, "加藤", PAN, "4");
 33|  myinput(lpdata + 4, "山田", KYO, "15.2");
 34|  myinput(lpdata + 5, "遠藤", PAN, "3");
 35|
 36|  printf("%4s %-14s %4s\n", "氏名", "競走名", "成績");
 37|  printf("----------------------------------\n");
 38|  for(i = 0; i < NO; i++){
 39|    printf("%4s %-14s ", data[i].name, data[i].kyogi);
 40|    if( strcmp( data[i].kyogi, "100m 競走") == 0){
 41|      printf("%4.1f秒\n", data[i].seiseki.tm);
 42|    } else {
 43|      printf("%4d位\n", data[i].seiseki.juni);
 44|    }
 45|  }
 46|  return 0;
 47|}
 48|
 49|
 50|int myinput (LPDATA p, char *nm, char *kg, char *sk)
 51|{
 52|  strcpy(p->name, nm);
 53|  strcpy(p->kyogi, kg);
 54|  if(!strcmp(kg, PAN)){
 55|    p->seiseki.juni = atoi(sk);
 56|  } else {
 57|    p->seiseki.tm = atof(sk);
 58|  }
 59|  return 0;                                                                           
 60|}

実行結果

氏名 競走名      成績
----------------------------------
田中 パン食い競走    1位
佐藤 100m 競走    20.5秒
河野 パン食い競走    2位
加藤 パン食い競走    4位
山田 100m 競走    15.2秒
遠藤 パン食い競走    3

Chapte8 @ C言語目録 @ HomeWork List @ 昭亮's Homepage