構造体

同じ型の変数をまとめて扱いたい時は配列を用いました。
しかし、アプリケーションを作成していると幾つかの異なった型の変数をまとめて扱いたいケースが頻繁にあります。
例えば、ある中学校でのクラスの平均点を求めるプログラムを作成したい場合、配列では1つの教科しか扱えない為に教科毎に処理を行う必要があります。
また、各教科の点数だけではなく生徒の名前も一緒に管理したいかもしれません。
このような時、幾つかの変数をまとめて1つの型と定義するのが構造体と呼ばれる仕組みです。

構造体

構造体は次のように宣言されます。

struct 構造体名 {
    変数1;
    変数2;
    ・
    ・
};

変数の数は幾つであっても構わず、構造体の変数をメンバと呼びます。

国語・数学・英語の3教科の点数を含む構造体を使用したプログラムは次のようになります。
[example07.c]

#include <stdio.h>

int main(int argc, char *argv[])
{
    struct score
    {
        int kokugo;
        int suugaku;
        int english;
    };
    struct score s;
    s.kokugo = 54;
    s.suugaku = 88;
    s.english = 79;
    printf("合計点は%dです。", s.kokugo + s.suugaku + s.english);
    return 0;
}

構造体の定義を行っているのはこの箇所です。

    struct score
    {
        int kokugo;
        int suugaku;
        int english;
    };

scoreというのが構造体の名前になります。
この名前を使い以下のように構造体の変数sを宣言します。

    struct score s;

この時、scoreはint型(4byte)のメンバを3つ持つ構造体である為、12byteがメモリ上に確保されます。

    s.kokugo = 54;
    s.suugaku = 88;
    s.english = 79;
    printf("合計点は%dです。", s.kokugo + s.suugaku + s.english);

ここでは各教科の点数を代入し、合計値を計算しています。
構造体のメンバは、

    構造体変数名.メンバ名

でアクセス可能であり、各メンバに対して代入することや値を参照することが可能です。

このように構造体を使えば、複数のデータをまとめて扱うことが可能となります。

構造体の配列

構造体の配列を作れば、大量のデータをまとめて処理するときに効率がよくなります。
[example08.c]

#include <stdio.h>

int main(int argc, char *argv[])
{
    struct score
    {
        int kokugo;
        int suugaku;
        int english;
    };
    struct score s[3];
    s[0].kokugo = 54;
    s[0].suugaku = 88;
    s[0].english = 79;
    s[1].kokugo = 50;
    s[1].suugaku = 60;
    s[1].english = 90;
    s[2].kokugo = 80;
    s[2].suugaku = 70;
    s[2].english = 40;
    int i;
    int total_kokugo = 0;
    int total_suugaku = 0;
    int total_english = 0;
    int size = sizeof(s) / sizeof(s[0]);
    for(i = 0; i < size; i++)
    {
        total_kokugo = total_kokugo + s[i].kokugo;
        total_suugaku = total_suugaku + s[i].suugaku;
        total_english = total_english + s[i].english;
    }
    printf("平均点(国語)は%dです。\n", total_kokugo / size);
    printf("平均点(数学)は%dです。\n", total_suugaku / size);
    printf("平均点(英語)は%dです。\n", total_english / size);
    return 0;
}

構造体の配列は通常の変数の配列と同じようにサイズを指定して宣言します。
次の例ではint型3つの構造体(12byte)でサイズが3の配列を宣言しているので合計で36byteのメモリが確保されます。
この時、4byte毎に最初の生徒の国語の点数、数学の点数、英語の点数、続いて2番目の生徒の国語の点数・・・という形でメモリに格納されています。

    struct score s[3];

従って、s[1].englishと配列を使う場合は36byte中の13byte目から3つ目のメンバ、すなわち21byte目にあるデータとなるのです。
このように構造体と配列を組み合わせると複雑なデータでも大量に扱えるようになります。
しかし、それはプログラマがメモリを意識しなくてはならない、ということにもなります。

さて、次はJava入門の為のC言語講座の最終回、ポインタのお話です。