構造体

[PDF版] [関連課題]

構造体(structure)とは

構造体とは、プログラムを論理的にわかりやすく書くための機能です。プログ ラムとは、コンピュータに何かをさせるための指示を与えるという役割があり ますが、人間のプログラマにとってはコンピュータの中で何かをさせたい場合 にそれを表現するための道具でもあります。

例えば、成績表を集計するプログ ラムを考えてみましょう。人間がやるのであれば表という形で表現するでしょ う。算数、国語、理科と3科目とすると、人数を縦、3科目の点数を横にとる 表をつくります。これをプログラムで表現するには2次元配列をつくります。 人数を50人とすると、

int seiseki_hyou[50][3];
となります。これで、例えば、10番の人の国語の成績を参照するには seiseki_hyou[9][1]となるわけです。初めの列は算数、次の列は国語、その次 は理科とするわけです。つまり、算数、国語、理科を数字に割り当てるのです が、プログラムでは数字になっていますので、他人が見たときにはわかりにく くなってしまいます。自分でも後になって、プログラムをみたときに思い出す のに時間がかかってしまうということもありえます。このような時に使うのが 構造体です。

次のように、算数と国語、理科の成績をひとまとまりにしてデー タ(の型)として名前をつけておくことができます。

struct seiseki {
  int sansu;
  int kokugo;
  int rika;
};
成績というデータは、3つのkokugo, sansuu, rikaの3つの値であると定義す るわけです。これを使えば、表を次のように宣言できます。
struct seiseki seiseki_kyou[50];
これを使えば、10番目の国語の成績は、seiseki_hyou[9].kokugoと表現す ることができます。

次に、住所録を管理するプログラムを考えてみることにしましょう。これも住 所録を作るデータを火とまとまりにして、構造体を定義すると便利です。

struct personal_record {
   char name[10];     /* 名前をいれる */
   int age:           /* 年齢 */
   char address[100]; /* 住所 */
   int tel[11];       /* 電話番号 */
};
このように、整数だけでなく、いろいろなデータをひとまとまりに構造体とし て定義することができます。構造体の中の要素のデータの名前をフィールド (field)、またはメンバー(member)と言います。構造体の定義 は、以下のように宣言します。
struct 構造体の名前 {
    フィールドのデータ型 フィールド名;
  フィールドのデータ型 フィールド名;
  …
};

構造体の「構造」とはデータ構造の「構造」です。プログラムでデータを論理 的に扱うためにどのようなデータをひとまとまりにすればわかりやすいかを考 えることがデータの構造を考えることなのです。

構造体の変数、配列、参照

構造体の宣言(定義)はデータの形だけを定義するものです。最初に配列の例 を挙げてしまいましたが、構造体のデータ型をもつ変数を宣言するには、以下 のように宣言します。
struct 構造体の名前 変数名;
例えば、2次元座標上の点をあらわすには次のような構造体を宣言します。
struct point { 
    double x, y; 
};
フィールドxとyが同じデータ型の時には上のように一緒に宣言できます。もちろん、別々に宣言してもOKです。これを使って、座標上の点をあらわす変数pは以下のように宣言します。
struct point p;

また、構造体の宣言と、変数の宣言を一緒にすることもできます。

struct point { 
   double x,y;
} p;

さて、メンバーを参照するには、”.”を使います。

構造体への参照 . メンバー名
です。例えば、pのx座標を参照するには、
t = p.x;
この参照は、代入側にも使えます。そのときには、メンバーへの代入になります。
p.x = 199;

最初の例で示したとおり、構造体の配列の宣言は、

struct 構造体の名前 配列名[サイズ];
です。例えば、10個の座標の配列は以下のようになります。
struct point points[10];
参照は、例えば、points[1].xとすればいいわけです。

データ型とは(再び)、typedef宣言

int やdouble, char, floatなどは基本的な数値に関するデータ型を基本デー タ型(basic data type)といいます。また、int *は「整数型データへのポイ ンタ」というデータ型です。これについては、前回説明しました。さらに言え ば、任意のデータ型Tに対して、T *は「データ型Tに対するポインタ」のデー タ型です。struct 構造体名もデータ型です。したがって、struct 構造体のデー タ型を持つデータへのポインタは、struct 構造体 * です。この意味につい ては、次回説明することにして、データ型Tを持つ変数や配列は、

T 変数名; 
または 
T 配列名[サイズ];
と宣言しますので、構造体の変数や配列は、
struct 構造体名 変数名; 
または 
struct 構造体名 配列名[サイズ];
と宣言するわけです。

データ型には、typedef宣言を使って、名前をつけることができます。データ 型Tに対して名前をつけるには、以下の宣言します。

 typedef T データ型名;
例えば、前の座標のデータ型に名前point_tという名前をつけるには以下のよ うに宣言します。
typedef struct point { 
    double x,y;
} point_t;
こうしておけば、座標の変数や配列は以下のように宣言できます。(_tはタイプのt)
point_t p;  
point_t points[10];
文字列は、文字へのポインタでしたね。 文字列のデータ型string_tを宣言するには、以下の宣言をします。
typedef char * string_t;

あるデータ型に対して、適当な名前をつけておけば、プログラムがわかりやす くなり、書きやすくなります。プログラミングとは、やりたいことを論理的に わかりやすく表現することでもあるのです。