C言語で成績管理システムを作る【第1回】【構造体/配列/点数計算】

目次

この記事について

「C言語で成績管理システムを作る」シリーズの第1回です。仕様決めまでの経緯は全体像の記事にまとめているので、そちらもあわせてどうぞ。

成績管理システムはC言語の課題としてもよく出される定番のお題です。
もし課題で調べに来た方は、コードをそのまま写すのではなく、「なぜこの設計にしたか」の部分を読んでから自分で書いてみることをおすすめします。

このステップでは、以下の範囲を実装します。

  • 学生5人分の名前・点数を構造体で管理
  • 構造体の配列で複数人分を保持
  • 平均点・最高点・最低点を計算して表示
  • 全員分の成績を一覧表示

データはひとまずソースコード内に直接書き込む形にして、動作確認をしやすくしています(キーボード入力への対応は次のステップで扱う予定です)。

実行結果とソースコード

先に、完成したプログラムと実行した結果を載せておきます。

実行結果

成績一覧が桁揃えされて表示され、平均点・最高点・最低点(学生名付き)まで正しく計算できています。

ソースコード

/*
 * 成績管理システム(パターン1: データ埋め込み版)
 * Visual Studio 2026 で動作確認想定
 * プロジェクト: 空のプロジェクト(C++)に .c ファイルとして追加すればOK
 */
#include <stdio.h>

#define MAX_NAME     32   /* 名前の最大文字数(終端の\0を含む) */
#define NUM_STUDENTS 5    /* 学生数 */

/* 学生1人分のデータ */
struct Student {
    char name[MAX_NAME];
    int  score;           /* 0〜100点を想定 */
};

/* --- 関数プロトタイプ宣言 --- */
void   print_all(const struct Student s[], int n);
double calc_average(const struct Student s[], int n);
int    find_max_index(const struct Student s[], int n);
int    find_min_index(const struct Student s[], int n);

int main(void)
{
    /* データはソースコード内で初期化(パターン1) */
    struct Student students[NUM_STUDENTS] = {
        { "Sato",      85 },
        { "Suzuki",    92 },
        { "Takahashi", 58 },
        { "Tanaka",    74 },
        { "Watanabe",  67 }
    };

    int max_i, min_i;

    printf("===== 成績管理システム =====\n\n");

    /* 一覧表示 */
    print_all(students, NUM_STUDENTS);

    /* 統計情報 */
    max_i = find_max_index(students, NUM_STUDENTS);
    min_i = find_min_index(students, NUM_STUDENTS);

    printf("--- 統計情報 ---\n");
    printf("平均点: %.1f 点\n", calc_average(students, NUM_STUDENTS));
    printf("最高点: %d 点 (%s)\n", students[max_i].score, students[max_i].name);
    printf("最低点: %d 点 (%s)\n", students[min_i].score, students[min_i].name);

    return 0;
}

/* 全員分の成績を一覧表示する */
void print_all(const struct Student s[], int n)
{
    int i;

    printf("--- 成績一覧 ---\n");
    printf("番号  名前            点数\n");
    for (i = 0; i < n; i++) {
        /* %2d: 2桁右詰め, %-15s: 15文字左詰め, %4d: 4桁右詰め */
        printf("%2d    %-15s %4d\n", i + 1, s[i].name, s[i].score);
    }
    printf("\n");
}

/* 平均点を計算して返す(人数0のときは0.0を返す) */
double calc_average(const struct Student s[], int n)
{
    int    i;
    double sum = 0.0;

    if (n <= 0) {
        return 0.0;
    }
    for (i = 0; i < n; i++) {
        sum += s[i].score;
    }
    return sum / n;
}

/* 最高点の学生の添字を返す(同点なら先に見つかった方) */
int find_max_index(const struct Student s[], int n)
{
    int i;
    int max_i = 0;

    for (i = 1; i < n; i++) {
        if (s[i].score > s[max_i].score) {
            max_i = i;
        }
    }
    return max_i;
}

/* 最低点の学生の添字を返す(同点なら先に見つかった方) */
int find_min_index(const struct Student s[], int n)
{
    int i;
    int min_i = 0;

    for (i = 1; i < n; i++) {
        if (s[i].score < s[min_i].score) {
            min_i = i;
        }
    }
    return min_i;
}

今回使う環境

  • Windows 11
  • Visual Studio 2026(コードを書いて実行するツール)
  • Claude(AI)

VS2026のインストール方法は以下の記事で解説しています。

Visual Studio 2026 でのビルド/実行手順

Claudeにソースコード生成を依頼した際、Visual Studioでの実行手順を教えてくれたので、その手順に従って進めます。

新しいプロジェクトの作成

.cファイルを作成

「デバッグなしで開始(Ctrl + F5)」で実行

実行時のトラブル

デバッグコンソールで日本語が文字化け

「デバッグなしで開始」で実行した際、以下のように日本語の文字化けが発生してしまいました。

原因はソースファイルの保存形式(BOMなしUTF-8)とコンパイラの解釈のズレによるものでした。

原因の詳細と対処法を調べて別記事にまとめたので、同じ症状に困っている方はこちらも参考にしてみてください。

コードの解説

構造体の定義

struct Student {
    char name[MAX_NAME];
    int  score;
};

学生1人分のデータを「名前(name)」と「点数(score)」というひとまとまりの単位で表現しています。
MAX_NAME はマクロで定義し、後から文字数の上限を変えやすくしています。

なお、配列サイズは32ですが、実際に格納できる名前は最大31文字です。
C言語の文字列は末尾に終端文字 \0 を1文字分置く必要があるため、「配列サイズ = 入れられる文字数 + 1」という関係になります。仕様で「名前は最大31文字」としたのはこのためです。

配列での管理

struct Student students[NUM_STUDENTS] = {
    { "Sato",      85 },
    { "Suzuki",    92 },
    ...
};

構造体の配列にすることで、5人分のデータを1つの変数(students)にまとめて持たせています。

各関数には配列の先頭ポインタと人数(n)を渡す形にしており、人数が変わっても関数側は書き換えずに対応できます。

集計処理

平均点

平均点は、全員分の点数を合計してから人数で割るだけのシンプルな処理です。整数の点数を double型の変数に足し込むことで、小数点以下も含めた平均を計算しています。

double calc_average(const struct Student s[], int n)
{
    int    i;
    double sum = 0.0;

    if (n <= 0) {
        return 0.0;
    }
    for (i = 0; i < n; i++) {
        sum += s[i].score;
    }
    return sum / n;
}

最高点・最低点の集計処理

最高点・最低点は、点数そのものではなく「何番目の学生か(配列の添字)」を返す設計にしています。

int find_max_index(const struct Student s[], int n)
{
    int i;
    int max_i = 0;

    for (i = 1; i < n; i++) {
        if (s[i].score > s[max_i].score) {
            max_i = i;
        }
    }
    return max_i;
}

こうすることで、呼び出し側(main関数)で点数と名前の両方を取り出せるようになっています。

まとめ

  • 構造体+配列を使うことで、複数人分のデータをまとまった形で管理できた
  • 集計処理(平均・最高・最低)は関数分割しておくと見通しが良い
  • 第2回では、キーボード入力(scanf)への対応を予定

最後まで読んでいただき、ありがとうございました。

興味がある方は、シリーズの他の記事もあわせてどうぞ。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次