教えていただきたいのですが、C言語で名前と点数を入力して合計と平均を求めるというプログラムを作ったのですが、
main関数の中で情報入力、合計と平均の計算をしているのでそれぞれ入力関数、合計を求める関数、平均を求める関数というものを作ってmain関数をすっきりとさせたいのですがどうすればいいですか?
#include <stdio.h>
typedef struct{
char name[15];
int jpn;
int eng;
int math;
int sum;
} stdent;
typedef struct{
double sum;
double jpn;
double eng;
double math;
} Score;
void maxmin(stdent *, int);
main()
{
int i, n;
n = 5;
stdent person[n];
Score average;
average.jpn = 0;
average.eng = 0;
average.math = 0;
average.sum = 0;
for(i = 0; i < n; i++)
{
printf("Student No.%d \n",i + 1);
printf("Name? ");
scanf("%s", person[i].name);
printf("Japanese? ");
scanf("%d", &(person[i].jpn));
printf("English? ");
scanf("%d", &(person[i].eng));
printf("Math? ");
scanf("%d", &(person[i].math));
printf("\n");
person[i].sum = person[i].jpn + person[i].eng + person[i].math;
average.jpn += person[i].jpn;
average.eng += person[i].eng;
average.math += person[i].math;
average.sum += person[i].sum;
}
average.jpn /= n;
average.eng /= n;
average.math /= n;
average.sum /= n;
printf(" 名前 国語 英語 数学 \n");
printf("------------------------------------\n");
for(i = 0; i < n; i++)
{
printf("%8s %3d %3d %3d %3d\n", person[i].name, person[i].jpn, person[i].eng, person[i].math, person[i].sum);
}
printf("------------------------------------\n");
printf("平均 %.1lf %.1lf %.1lf %.1lf\n\n", average.jpn,average.eng,average.math,average.sum);
return 0;
}
No.3ベストアンサー
- 回答日時:
こんな感じでどうでしょうか?
=== ここからソース ==============================================
// Seiseki.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//
#include "stdafx.h"
// 配列の要素数を計算するマクロです
// 毎回sizeof()で書くより
// プログラムがわかりやすくなります
#define ARRAY_OF(a) (sizeof (a) / sizeof (a[0]))
// 人数を定義します
#define STUDENT_COUNT5
// 成績を格納する領域です
// 構造体配列でも作れますが、教科を通じての合計を取るのであれば
// 2次元配列のほうが適しています
// 各教科のインデックス
#define JAPANEASE0// 国語
#define ENGLISH1// 英語
#define MATHEMATICS2// 数学
// 各教科名を格納しておきます
// 各教科のインデックス順に並んでいなければなりません
static char* SubjectName[] = {"国語", "英語", "数学"};
// 個人の成績用構造体です
// 各教科毎に別のフィールドにせず
// 配列にしたほうが
// 合計や平均をとる関数がすっきりします
#define MAX_NAME_LENGTH 15// 氏名の最大長です
struct student
{
char Name[MAX_NAME_LENGTH + 1];// 氏名
int Score[ARRAY_OF (SubjectName)];// 各教科の得点
};
// データ格納域
// 2次元配列です
// 1次元目で生徒を識別します
// 2次元目で科目を識別します
static struct student person[STUDENT_COUNT];
// 合計を求める汎用関数です
// int型専用です
static int GetTotalInt(int Data[], int Count)
{
int s = 0;
int i;
for (i = 0; i < Count; ++i)
{
s += Data[i];
}
return s;
}
// 合計を求める汎用関数です
// doble型専用です
static double GetSumDoble(double data[], int Count)
{
int i;
double s = 0;
for (i = 0; i < Count; ++i)
{
s += data[i];
}
return s;
}
// 指定教科の合計点を求めます
static int GetSubjectsTotal(int SubjectNo)
{
int s = 0;// 合計用
int i;// 生徒用
for (i = 0; i < ARRAY_OF(person); ++i)
{
s += person[i].Score[SubjectNo];
}
return s;
}
// 指定教科の平均点を求めます
static double GetSubjectsAverage(int SubJectNo)
{
return GetSubjectsTotal(SubJectNo) * 1.0 / (ARRAY_OF(person));
}
// 成績を入力させる関数です
void InputData()
{
int i;
// 生徒数分データを入力させます
// ARRAY_OFにより人数を計算しているので
// 生徒数が変わっても、
// ここは全く変更の必要がないことに注目してください
for (i = 0; i < ARRAY_OF (person); ++i)
{
int j;
printf("Student No.%d \n", i + 1);
printf("Name? ");
scanf("%s", person[i].Name);
// 各教科の得点を入力させます
// 各教科の得点を配列にしたことで
// ARRAY_OFによる教科数の計算が可能になりました
// 教科の名称をテーブル化したことで
// 教科に増減・変更があっても
// ここの部分は全く変更を受けません
for (j = 0; j < ARRAY_OF (person[0].Score); j++)
{
printf("%s? ", SubjectName[j]);
scanf("%d", &(person[i].Score[j]));
}
}
}
// 成績を表示します
static void DisplayScore()
{
int i;
double Ave[ARRAY_OF (SubjectName)];// 教科毎の平均値格納用
printf("名前 ");
// 教科名を列挙します
for (i = 0; i < ARRAY_OF (SubjectName); i++)
{
printf("%s ", SubjectName[i]);
}
printf("\n");
// 生徒の成績を合計とともに表示します
for (i = 0; i < ARRAY_OF (person); i++)
{
int j;
// 氏名を表示します
printf("%15s ", person[i].Name);
// 教科別の得点を表示します
for (j = 0; j < ARRAY_OF (person[0].Score); j++)
{
printf("%3d ", person[i].Score[j]);
}
// 合計を表示し改行します
printf("%3d\n", GetTotalInt(person[i].Score,
ARRAY_OF (person[0].Score)));
}
// 各教科の平均点を表示します
// 平均の合計を取りやすくするため、一旦配列に格納します
printf("平均 ");
for (i = 0; i < ARRAY_OF (person[0].Score); i++)
{
Ave[i] = GetSubjectsAverage(i);
printf("%.1f ", Ave[i]);
}
// 平均の合計を表示します
printf("%.1f", GetSumDoble(Ave, ARRAY_OF(Ave)));
}
int main(int argc, _TCHAR* argv[])
{
// 成績を入力させます
InputData();
// 結果を表示します
DisplayScore();
return 0;
}
===================== ここまで ソース =====================
ポイントは
各関数の役割分担を明確にすること
各関数に必要以上の知識を持ちこませないこと
各関数には役割にふさわしい名前をつけること
です。
例えば、教科毎の合計を求める関数では
各人のデータが分かればよいのです。
具体的な教科名を知る必要性は全くないです。
そのためには、jpn, engといった教科と結びついた変数でなく
配列を使うのです。
配列を使うことで具体的な教科を隠し、
単なる得点データへと抽象化します。
抽象化することで教科と分離されたので
教科が変更になっても
(例えば 国語の代わりに理科を入れる)
変更は最小限で済みます
教科ごとの集計関数などは全く影響を受けず、
プログラム的にもスッキリします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンパイルエラーについて
-
コマンドラインに出力した文字...
-
【C初心者】+,-,*./について【...
-
台形の面積を求めるプログラム
-
じゃんけんゲームをつくったの...
-
迷路作成のプログラミング
-
C言語での、年複利の計算方法...
-
error C2143: 構文エラー : ';'...
-
cshの文字列操作(0埋め)
-
printf で二進表示を行いたい。
-
スレッドとメッセージキューに...
-
#include <stdio.h> #include <...
-
教えてください!!
-
C言語のプログラムにエラーが出...
-
printfでSegmentation fault
-
Cプログラムについて
-
Cプログラムについて
-
なぜgccはstdio.hをインクルー...
-
C言語のじゃんけんゲームのプロ...
-
学校の課題で
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
テキストカーソル位置の取得
-
4の倍数を論理演算で表す。。
-
cshの文字列操作(0埋め)
-
【C言語教えてください】sin波...
-
10個出力で改行したいのですが...
-
wsprintfの書式制御文字列につ...
-
error C2143: 構文エラー : ';'...
-
printfの出力内の文字をdefine...
-
%P と %X の違い
-
C言語
-
strcmp
-
(C言語)めちゃくちゃな値にな...
-
コマンドラインに出力した文字...
-
スレッドとメッセージキューに...
-
printf( " %2d", p * q );
-
Visual Sutdio 2017 でのC言語...
-
defineで定数が置き換えられな...
おすすめ情報