構造体1


1.構造体とは

 1つの名前をもち、1つまたはそれ以上の異なる型の変数の集まりです。他のプログラミング言語では、「レコード」と呼ばれています。

上の図は、int型の変数x,yを一まとめにして扱うために構造体を作る例です。この例では、変数x, yともにint型ですが、構造体には異なる型の変数を含むことができます。上のような構造体を宣言するには、

    struct point {
       int x;
       int y;
    };

 のように書きます。ここで、「struct」の後に書かれている「point」という名前を構造体タグ名といいます。タグ名によって他の構造体と区別することができます。構造体の中で宣言されている変数(ここでは、xとy)をメンバ(member)といいます。メンバ名は、異なる構造体の中では同じメンバ名を使ってもよいことになっています。構造体が異なれば、同じメンバ名でも区別できるからです。

 さて、上の構造体の宣言は、構造体の形を宣言しただけです。まだ、構造体を使えるようにはなっていません。このような形の構造体を使うためには、

   struct point a;

のように構造体変数を宣言しなければなりません。上の宣言によって、aという名前の構造体変数が使えるようになります。

 構造体の中のメンバを使うときは、

   構造体変数名.メンバ名 のように書きます。

例えば、構造体変数aの中のメンバxの場合は、  a.x   のように、ピリオドを使って書き表します。
メンバyは、  a.y   と書きます。

 構造体変数の宣言は、構造体の宣言と同時にすることもできます。

    struct point {
       int x;
       int y;
    } a;

 この書き方の場合は、構造体の宣言と構造体変数の宣言が同時に行われています。もし、構造体変数の宣言をここでしかしないのであれば、タグ名を省略して、

    struct {
       int x;
       int y;
    } a;

 と書くこともできます。但し、他のところで、別の変数を宣言することはできません。タグ名をつけておけば、

   struct タグ名 変数名, 変数名, ・・・・;

のように他のところででも何度でも宣言できます。


2.構造体に対してできる演算は

 構造体に対してできる演算は、代入(つまりコピー)、&でアドレスを求めること、そのメンバにアクセスする、この3つだけです。

    struct {
       int x;
       int y;
    } a, b;
    a.x = 10; /* メンバxに10を代入 */
    a.y = 20; /* メンバyに20を代入 */
    b = a; /* 構造体変数aの内容をbに代入 */

上のプログラムの最後の行のように、同じ形の構造体に内容を代入する(コピー)することができます。

このコピー(代入)には、関数へ引数として構造体変数を渡すことができること、関数の戻り値として構造体変数を返せることを含んでいます。


3.構造体の宣言(その2)

 typedef文を使って構造体を自作の型として定義できます。「typedef文は」型に新しい型名をつけるための文です。例えば、

    typedef unsigned int UI;

と宣言することによって、これ以降は、「unsigned int」と書く代わりに、「UI」と書くことができます。このtypedefを使って、

    typedef struct point {
       int x;
       int y;
    } Point;

のように定義すると、これ以降は、「struct point」と書く代わりに「Point」だけで済ませることができます。普通の型の「int」や「double」と同じように、

    int a;
    Point b;

のように構造体変数を宣言することができます。


4.構造体変数の初期化

 構造体変数の初期化は、配列と同じように、「」「」でメンバの値をカンマで区切って指定します。

    struct point {
       int x;
       int y;
    } a = { 10, 20 };

 また、多少複雑な構造体でも、

    struct polygon {
       int x[5];
       int y[5];
    } a = { {10, 20, 30, 40, 50}, {60, 70, 80, 90, 100} };

のように初期化します。


5.例題プログラム31(rei31.c)

 上の例のstruct pointint型の構造体変数aのメンバにキーボードから数値を入力し、そのままの値を出力するプログラムを作りましょう。

例題プログラム31(rei31.c)
/* 構造体 */
#include <stdio.h>
main(int argc, char *argv[])
{
        struct point {
                int x;
                int y;
        } a;

        printf("構造体のメンバに数値を入力します\n");
        printf("a.x = ");
        scanf("%d", &a.x);
        printf("a.y = ");
        scanf("%d", &a.y);
        printf("a.x = %d\n", a.x);
        printf("a.y = %d\n", a.y);
}

 5行目〜8行目で構造体pointを宣言するとともに、変数aも宣言しています。この宣言によって、メンバx, yを持つ構造体変数aが使えるようになります。
 12行目で、メンバa.xに数値をキー入力しています。また、14行目で、メンバa.yに数値をキー入力しています。15行目、16行目でメンバの内容を出力しています。