納得C言語!
演習問題W 第3問の解答
3 役職ごとの平均給与
解答プログラム
//プログラムを書くときには「(1),(2),(3)」は書かないでください
#include <stdio.h>
#include <string.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; // 給与(構造体)
};
// 関数のプロトタイプ宣言
void fp_avg(struct shain *p);
int main()
{
int i = 0;
struct shain list[256];
struct shain *p;
p = list;
//社員データ入力
//説明は(1)でやっているので省略します
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%11s%8s%6s%10d%10d%10d\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
);
}
fp_avg(p);
return 0;
}
//役職ごとの3ヶ月平均給与
void fp_avg(struct shain *p)
{
int sum=0; //合計用
int i=0; //ポインタ用
int j=0; //人数カウント用
char *str;
//strに1人目の役職をコピー
(1)str = p->fp;
printf("\n役職ごとの3ヶ月の平均給与\n");
//(p+i)->noが0になるまで繰り返す
while(((p+i)->no)!=0){
//strと(p+i)->fpを比較し同じ役職であれば繰り返す
while((2)strcmp(str,(p+i)->fp)==0){
//sumに現在の社員の給与を格納(この時sum自身も加算します)
sum = sum + (p+i)->money.kyu_apl + (p+i)->money.kyu_mar + (p+i)->money.kyu_jun;
//ポインタを一つ進める
i++;
//人数をカウント
j++;
}
//役職の平均給与を算出し表示
printf(" 役職 給与額\n");
printf("%6s %10d\n",str,sum/(j*3));
(3)//人数と合計をで初期化
j=0;
sum=0;
//strを初期化し次の役職を格納する
str = "";
str = (p+i)->fp;
}
}
解説
社員データの入力と表示は(1)、(2)と同じですね。
自作関数内の説明に入ります。
(1)で1人目の役職をstrに格納します。
まず「部長」がstrに格納されますね。
(2)ではstrと(p+i)->noの比較をしています。
このときiは0なので(p+0)->noとstrを比較。
「部長」で同じなのでwhile文の中を実行します。
sumにsumとその社員の3ヶ月分の給与を代入します。
また、iとjの値に1加算します。
そして再びstrcmpで比較します。
まだ部長で同じですね。
なので、sumにsumと2人目の社員の給与を代入します。
iとjが3まできました。
(3)で比較をすると、strは部長ですが、(p+3)->fpは課長ですね。
なので今回でwhile文から抜け出します。
抜け出したあと、strの役職の平均給与を計算し、表示しています。
このままではjにこれまでの人数が、strに前の役職が格納されたままなので、網掛けの部分で初期化します。
初期化されると下のようになります
strに課長、jに0が格納されましたね。
これを、社員番号が0になるまで繰り返します。
このくらいのプログラムが書けるようになれば、C言語を理解できたといえるでしょう
あとがき
C言語の学習の方は順調でしょうか?
今回はC言語で最も難しいと言われているポインタと構造体の学習を行いました。
ポインタや構造体は理解するのに時間がかかりますが、使いこなすことが出来ると本当に便利です。
正直、今回の学習ではポインタや構造体の全てを語りきることが出来ませんでした。
この学習を終えて、ポインタや構造体をもう少し詳しく知りたいと思った時にさらに深いところまで調べるといいでしょう。
今よりさらなる壁が立ちはだかりますが、それを乗り越えた時には間違いなくC言語の知識を身に付けたと実感しますよ。
さて、次回はいよいよ最終回です。
ここまでたどり着いたあなたならもう怖いものなしでしょう。