C言語のきほん「3教科の偏差値を表示してみよう」

スポンサーリンク
C言語

以前、本ブログでは、「分散と標準偏差を求めるように関数を追加してみよう」をご紹介した。

今回は、このプログラムを変更してみよう。

なお、このプログラムは、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クリエイティブ)

コメント

タイトルとURLをコピーしました