ほぷしぃ

納得C言語!

[第15回]演習問題W 第1問の解答

演習問題W 第1問の解答


1 社員給与表を作ってみよう

解答プログラム

#include <stdio.h>

// 構造体(3か月分の給与)
struct kyuyo
{
    int kyu_apl;    // 4月分
    int kyu_mar;    // 5月分
    int kyu_jun;    // 6月分
};

// 構造体(社員)
struct shain
{
    int no;                // 社員番号
    char name[256];        // 社員名
    char busyo[256];       // 部署名
    char fp[256];          // 役職
    struct kyuyo money;    // 給与(構造体)
};

int main()
{
    int i = 0;

    // 構造体の宣言(配列)
    struct shain list[256];

    // 構造体ポインタの宣言
    struct shain *p;

    // ポインタにlist構造体の先頭アドレスを代入
    p = list;

    while(1){
        // 構造体にデータを入力
        printf("社員番号:");
        scanf("%d",&(p+i)->no);

        // 社員番号にが入力されたら終了
        if((p+i)->no==0){
            break;
        }

        printf("社員名:");
        scanf("%s",(p+i)->name);
        printf("部署:");
        scanf("%s",(p+i)->busyo);
        printf("役職:");
        scanf("%s",(p+i)->fp);
        printf("給与\n");
        printf("4月:");
        scanf("%d",&(p+i)->money.kyu_apl);
        printf("5月:");
        scanf("%d",&(p+i)->money.kyu_mar);
        printf("6月:");
        scanf("%d",&(p+i)->money.kyu_jun);
        i++;
        printf("\n");
    }

    // 入力されたデータの表示
    printf("                      給与\n");
    printf("社員番号   氏名  部署 役職   4月   5月   6月\n");

    for(i=0;(p+i)->no!=0;i++){
        printf("%8d%10s%8s%6s%9d%9d%9d\n",
            (p+i)->no,
            (p+i)->name,
            (p+i)->busyo,
            (p+i)->fp,
            (p+i)->money.kyu_apl,
            (p+i)->money.kyu_mar,
            (p+i)->money.kyu_jun
            );
    }

    return 0;
}

解説

まず、4〜6月分の給与を格納する構造体の型を宣言します。
次に、社員情報を格納する構造体の型を宣言します。
このとき、給与の構造体の型宣言は、社員情報の構造体宣言より先に行わなくてはなりません。
次に、社員情報構造体の宣言と、その構造体へのポインタを宣言し、アドレスを渡してあげます。

社員情報を格納していくときは、人数がわからない場合が多いので無限ループで0が入力されたら終了としておきましょう。
また、無限ループを抜けるタイミングは社員番号が入力されたら判別するようにすれば楽になります。

表示は例題と同じですね。

今回は構造体の入れ子というちょっと応用的な問題になりました。
構造体の構造体をポインタで呼び出すときやりがちなミスとして

(p+i)->money->kyu_apl

と書いてしまうかもしれません。
しかし、kyuyo構造体へのポインタはないので、kyuyo構造体の参照はドット演算子( . )を使用します。


ヒント ページのトップ 第2問