STEP 10 - 構造体・共用体
 │
 ├ 構造体構造体の定義構造体データの使用宣言構造体のメンバ参照構造体メンバの初期化構造体配列構造体のポインタ変数構造体配列をポインタで参照する共用体共用体の定義・参照共用体によるメモリ領域の確保共用体変数の宣言typedef句
猿でも解る C言語講座

Written by Yuki.
http://ftc.suki.net/

<構造体>  int型・char型等、数種の型を 1つの情報として扱う時、  例えば住所録や名簿等で 1人当たりのデータに文字・数字を同居させる時に使う。  構造体を使うメリットは、一纏まりの処理がある時ばらばらにせずに、  解り易く書ける事である。変数の数も削減できる。
<構造体の定義>  構造体では、その名前がタグと呼ばれる。  struct 構造体タグ名{    型 要素1; ' 構造体を構成する要素の事をメンバという。    型 要素2; ' それぞれ メンバ1・メンバ2・メンバ3 となっていく。    型 要素3;  };  structと記述する事により、構造体の定義である事を知らせる。宣言方法は変数・配列と同じ。  呼び方が違うだけで、配列の定義と何ら変わりはない。型は C言語で使用できるものを使う。
<構造体データの使用宣言>  サブルーチンの時の様に、定義以外に使用時にも宣言が必要である。  struct 構造体タグ名 構造体変数名; ' 構造体がどんなメンバで構成されているのか識別する。  (使用例)   #include <stdio.h>   struct kouzoutai1{     char name[16];     char jyuusyo[31];     char tel[13];     int yuubin;   };   void main()   {     struct kouzoutai1 area;     area.yuubin=162; ' 構造体メンバの参照(アクセス)。   }  area に yuubin の内容 162が入る。
<構造体のメンバ参照>  上の使用例の構造体メンバの参照の書式。  構造体変数名.メンバ名 ' 間にピリオドを入れる。変数に参照するメンバの内容が入る。  構造体変数は構造体とデータを繋ぐパイプになっている。  この変数は型に捕われずにデータを構造体に送る事ができる。  (使用例)   構造体のメンバ name を参照。   gets(area.name); ' char型の配列。areaに入力した文字列が入る。  添え字は付けない(nameの先頭アドレスを示す事になる)。   構造体のメンバ yuubin を参照。   scanf("%d",&area.yuubin); ' 入力された数値は yuubin から area へ移る。  アドレス演算子は構造体変数の前に付ける。  ※こういった構造体は、例えば RPGのキャラクターの能力データを管理するのに使える。   struct param{     int HP;     int MP;     char name[16];     ・     ・     ・   };   struct param player; ' playerという構造体変数で、それぞれ指定したメンバにデータを入れていく。   player.HP=100; ' こうして書いていったものが、上の構造体のメンバとして記憶される。   player.MP=100;   player.name[16]="〜";
<構造体メンバの初期化>  構造体の定義時に、構造体変数も一緒に定義できる。  struct kouzoutai1{    char name[16];    char jyuusyo[31];    char tel[16];    int yuubin;  }area;   ' 最後に変数名を書く。これが構造体変数になる。  areaの後ろにメンバ毎の初期値を宣言する事もできる。  }area={"namae","jyuusyo","denwabangou",999};  文字列配列の初期化の時と同様の書き方をする。  それぞれがメンバに対応するが、もちろん型は一致している必要がある。  構造体変数の宣言時にも同様に初期化を行える。  void main()  {    struct kouzoutai1 area={"namae","jyuusyo","denwabangou",999};    puts(area.name); ' 構造体の name の中身、namae を出力。  }  C言語の種類によって、この書き方は通用しない事がある。
<構造体配列>  構造体も配列にする事ができる。  struct kouzoutai1 area[3]; ' これは、変数名[n] の数だけ構造体が存在すると考える。  この場合、kouzoutai1 は 0,1,2 の 3つがある事になる。  構造体の配列は、各メンバが配列を持っているのだが、  構造体それ自体が配列になっていて、変数の下に構造体があると考えた方が解り易い。  struct kouzoutai2{    int no;    char address[50];    char name[30];  }area[10];    ' 変数定義と同時に配列を宣言。  これは言うなれば三次元配列であり、1人の名前・住所等を書いた構造体を複数作る事で、名簿等に活用できる。  void main()  {    area[0].no=1; ' 0番目の構造体の no に 1を代入する。    ・    ・    ・  }  ※初期化する文字列・値を省略すると、ヌル文字・0が入る。  ※これらの構造体の使用法を組み合わせ、二次元配列の初期化の時と同様に構造体配列を初期化したり、   ループで構造体を初期化したり、1つの構造体に複数の配列を持たせる事もできる。
<構造体のポインタ変数>  構造体を参照するには、ポインタを利用するのが一般的である。  struct tag00{    int i;    char str[80];  };  struct tag00 s;  struct tag00 *p;  ' 構造体 tag00 を基底型としたポインタ変数。  p=&s;  ' pに構造体変数 sのアドレスを代入する。構造体変数のアドレスを   ポインタ変数へ代入すると、ポインタは構造体の先頭アドレスを指す。  s.i=100;  p->i=100;  ' 構造体ポインタ変数ではマイナス記号と不等号を組み合わせた   記号(アロー演算子)を使う。これは上のピリオドと同じ役割を果たす。
<構造体配列をポインタで参照する>  struct tag00{    int i;    char str[80];  }s[5],*p;  ' 構造体配列とポインタ。  p=s;  ' 配列名のみ書く事で、構造体配列の先頭アドレスを pへ代入。  p->i=100;  ' sの 0番目のメンバ iに 100を代入する。  p++;  ' インクリメントすると、アドレスは基底型の 4バイト分加算される。   つまり配列の次の要素(s[1])に移動する。
<共用体>  1箇所のメモリ領域を 2つか、それ以上の変数や配列で共有すること。  これはコンピュータ上のメモリの最大値が小さかった頃に重要だったもので、最近は使われなくなっている。  しかし、Windows上のアプリケーションを作成するにあたり、共用体を使用する必要がある。
<共用体の定義・参照>  定義・参照の方法は構造体と類似している。  union 共用体タグ名{ ' キーワード "union" により、共用体の定義である事を    型 要素1;  コンピュータに知らせる。    型 要素2; ' 要素は C言語で有効なデータ型の変数・配列等。    型 要素n;  };
<共用体によるメモリ領域の確保>  (使用例)   int型・short int型の変数 2つ、char型配列(要素数 4つ)の共用体。   union tag00{     int i; ' 4バイト     short int x,y; ' 2バイト*2 このケースでは、共用体は 4バイトの     char s[4]; ' 1バイト*4 メモリ領域を確保する。   };   共用体として確保したメモリ領域を各要素で共有する。   上の要素を共用体無しで宣言すると 4*3 バイト使用する事になる。
<共用体変数の宣言>  変数の宣言の仕方も構造体とさして変わらない。  union tag00 u;  参照の仕方も構造体と同じく、ピリオド・アロー演算子を使用する。  u.i=100; ' 共用体変数名と要素名をピリオドで区切る。  p->i=100; ' ポインタで参照する時は、アロー演算子を使う。
<typedef句>  新しいデータ型を作成する。記述が面倒な長い句を簡略化する時に使用する。  typedef 既存のデータ型 新しいデータ型;  (使用例)   unsigned intu_int型 で定義する。   typedef unsigned int u_int;   u_int i; ' unsigned int i; と同じ。   unsigned int j; ' 既存のデータ型も使用できる。iと jは同じ型である。  (使用例)   構造体を新たなデータ型として定義する。   typedef struct tag00{ ' 既存のデータ型。     ・     ・     ・   }NEW_DATA; ' 新しいデータ型。要素数も指定すれば構造体配列を作れる。   NEW_DATA x; ' struct tag00 x;と同じ。要素数があれば x[n] となる。
← ← Back to BeforeStep Go to NextStep → →