以前、本ブログでは、「分散と標準偏差を求めるように関数を追加してみよう」をご紹介した。
今回は、このプログラムを変更してみよう。
なお、このプログラムは、Windows11(24H2)のPCで、Visual Studio Code(バージョン: 1.100.3 (user setup))で動作確認している。
教科の拡張
【変更前】 英語・数学の2教科のみ対象。
【変更後】 国語を追加し、3教科(英語・数学・国語)に対応する。
生徒数の柔軟化
【変更前】 #define NUMBER 5 で生徒数が固定。
【変更後】 ユーザーが任意の人数を実行時に入力可能とする。
構造体を導入
生徒1人あたりの情報(名前、点数、偏差値、合計点など)を管理するために、
構造体を導入。
コードの見通しと拡張性が向上する。
typedef struct { … }
Student;
偏差値の導入
各生徒について以下を計算する。
・各教科の偏差値(英語・数学・国語)
・3教科合計点の偏差値
偏差値の公式
偏差値=50 +$ \frac{(得点 – 平均)}{標準偏差} \times 10$
画面出力の整形No.
, 名前
, 英語
, 数学
, 国語
, 合計偏差値
などを整列表示する。
偏差値の小数点以下2桁表示で見やすく整形した。
/* 英語の点数と数学の点数と合計点の偏差値を求める*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define MAX_STUDENTS 100
#define SUBJECTS 3
typedef struct {
char name[100];
int scores[SUBJECTS]; // [0]:英語, [1]:数学, [2]:国語
int total;
double dev[SUBJECTS]; // 各教科の偏差値
double total_dev; // 合計点の偏差値
} Student;
/* 平均を計算 */
double mean(int data[], int n) {
double sum = 0.0;
for (int i = 0; i < n; i++)
sum += data[i];
return sum / n;
}
/* 標準偏差を計算 */
double stddev(int data[], int n, double avg) {
double sum_sq = 0.0;
for (int i = 0; i < n; i++)
sum_sq += (data[i] - avg) * (data[i] - avg);
return sqrt(sum_sq / n);
}
/* 偏差値を計算 */
double deviation(int score, double avg, double sd) {
return 50 + 10 * (score - avg) / sd;
}
int main(void) {
int n;
Student students[MAX_STUDENTS];
printf("生徒の人数を入力してください: ");
scanf("%d", &n);
// 点数入力
for (int i = 0; i < n; i++) {
printf("【%d人目】名前: ", i + 1);
scanf("%s", students[i].name);
printf("英語: "); scanf("%d", &students[i].scores[0]);
printf("数学: "); scanf("%d", &students[i].scores[1]);
printf("国語: "); scanf("%d", &students[i].scores[2]);
students[i].total = students[i].scores[0] + students[i].scores[1] + students[i].scores[2];
}
// 各教科の平均・標準偏差を求める
for (int subj = 0; subj < SUBJECTS; subj++) {
int temp[MAX_STUDENTS];
for (int i = 0; i < n; i++) {
temp[i] = students[i].scores[subj];
}
double avg = mean(temp, n);
double sd = stddev(temp, n, avg);
for (int i = 0; i < n; i++) {
students[i].dev[subj] = deviation(students[i].scores[subj], avg, sd);
}
}
// 合計点の偏差値計算
int totals[MAX_STUDENTS];
for (int i = 0; i < n; i++) {
totals[i] = students[i].total;
}
double avg_total = mean(totals, n);
double sd_total = stddev(totals, n, avg_total);
for (int i = 0; i < n; i++) {
students[i].total_dev = deviation(students[i].total, avg_total, sd_total);
}
// 出力
printf("\n【偏差値結果】\n");
printf("No.\t名前\t英語\t数学\t国語\t合計偏差値\n");
for (int i = 0; i < n; i++) {
printf("%d\t%s\t%.2f\t%.2f\t%.2f\t%.2f\n",
i + 1,
students[i].name,
students[i].dev[0],
students[i].dev[1],
students[i].dev[2],
students[i].total_dev);
}
return 0;
}
入力するデータ
名前: 太郎 → 英語: 80 数学: 70 国語: 75
名前: 次郎 → 英語: 60 数学: 55 国語: 50
名前: 三郎 → 英語: 90 数学: 95 国語: 85
実行結果
生徒の人数を入力してください: 3
【1人目】名前: 太郎
英語: 80
数学: 70
国語: 75
【2人目】名前: 次郎
英語: 60
数学: 55
国語: 50
【3人目】名前: 三郎
英語: 90
数学: 95
国語: 85
【偏差値結果】
No. 名前 英語 数学 国語 合計偏差値
1 太郎 52.67 47.98 53.40 51.16
2 次郎 36.64 38.89 36.41 37.21
3 三郎 60.69 63.13 60.19 61.62
(参考)
新・明解C言語 入門編 第2版 柴田望洋著(SBクリエイティブ)
新・解きながら学ぶC言語 第2版 柴田望洋・由梨かおる著(SBクリエイティブ)
コメント