コース一覧
    C言語中級 文字列・構造体
    つくる 動的Student完成

    C言語中級 文字列・構造体

    C言語の文字列と構造体を学び、複数のデータを整理して扱うコースです。

    1
    文字列処理の実践
    01. strlenを自作する15分
    02. strcpyを自作する15分
    03. バッファオーバーフロー体験15分
    04. 文字列を分解する15分
    05. 動的な文字列15分
    06. つくる 名前入力の安全化15分
    07. 第3章クイズ10分
    2
    構造体とポインタ
    01. 構造体ポインタと->15分
    02. 構造体の動的確保15分
    03. 動的な構造体配列15分
    04. 関数ポインタ15分
    05. qsortで並べ替える15分
    06. つくる 動的Student完成15分
    07. 第4章クイズ10分

    つくる 動的Student完成

    この章でやったことを 1 つにまとめる

    第 4 章では、構造体をポインタで触る ->、構造体をヒープに置く malloc(sizeof(Student))、人数ぶんまとめて借りる動的な構造体配列、表示のしかたを差し替える関数ポインタ、そして qsort による並べ替えを見てきました。今回は全部を 1 つのプログラムに入れて、成績管理の一覧部分を作り直します。

    作るもの

    入力は次の形で来ます。1 行目が表示のしかた、2 行目が人数、そのあとに人数ぶんの 名前 点数 が並びます。

    プレーンテキスト

    1
    4
    Sato 80
    Suzuki 95
    Tanaka 80
    Ito 73

    やることは 4 つです。人数ぶんの Student をヒープに確保して読み込み、点数の高い順に並べ替え、指定された形式で全員を表示し、最後に平均を小数第 1 位まで出します。表示のしかたは 1 なら 名前 点数、2 なら名前のあとに 点数 / 10 個の * を並べた棒グラフです。

    並びを一意にしておく

    上の例では Sato と Tanaka が同点です。点数だけで比べると、この 2 人のどちらが先に出るかは決まりません。前回書いたように、点数が等しいときは名前で比べて、並びが一意になるところまで決めてください。この例では Sato が先です。

    表示の選び方

    if で表示を分けるのではなく、先に関数ポインタへどちらかを入れてから、ループの中では選んだものを呼ぶ形にしてください。

    c

    void (*style)(const Student *) = print_plain;
    if (mode == 2) {
        style = print_bar;
    }

    こうしておくと、ループの中に判定が残りません。表示の種類が増えても、増えるのは if の枝だけでループは変わりません。

    平均の出し方

    点数は int なので、そのまま足して n で割ると小数が切り捨てられます。片方を double にしてから割ってください。表示は %.1f にします。%f のままだと小数第 6 位まで出ます。

    c

    printf("平均 %.1f\n", (double)sum / n);

    後始末

    malloc は 1 回なので free も 1 回です。表示や並べ替えが終わったあと、return の前に解放します。プログラムが終われば OS が回収してくれますが、この形をそのまま関数に切り出したときにリークが残るので、いまのうちから書く癖を付けておいてください。

    入門の成績管理と何が変わったか

    入門で書いた版は Student list[100]; のような固定長配列でした。100 人を超える入力は受け取れず、逆に 3 人しか使わない日でも 100 人ぶんの領域を抱えていました。人数の上限がコードに焼き付いていたわけです。

    今回の版には上限がありません。人数は実行時に決まり、必要なぶんだけ借ります。並べ替えも自分で書かず、大小の決め方だけを渡して qsort にやらせています。表示のしかたも走査から切り離しました。同じ「成績を一覧する」という仕事でも、どこを実行時に決められるようにするかで、コードの形はここまで変わります。

    残っている弱点は、途中に 1 人だけ挿入したいときです。動的配列は連続して並んでいるので、間に入れるには後ろを全部ずらすことになります。次の第 5 章では、ここを付け替えだけで済ませる連結リストに作り替えていきます。

    要件

    1. 人数分の Student をヒープに確保して読み込む
    2. 確保に失敗したら「確保できませんでした」と表示して return 1 する
    3. qsort で点数の高い順に並べ替える。同点なら名前の辞書順にする
    4. 1行目が 2 なら print_bar、それ以外なら print_plain を関数ポインタに入れて使う
    5. 最後に「平均 」に続けて平均点を小数第1位まで表示する
    6. 確保した領域を free する

    ヒント

    入力の順番は 表示形式、人数、学生の行 です。scanf を2回呼んでから確保します

    並べ替えは表示より先です。表示のループの中で点数を足していけば平均も出せます

    平均は (double)sum / n を %.1f で表示します

    生田 陸人
    監修生田 陸人
    ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
    編集 ゆめさく編集部·公開 2026/08/07

    関連レッスン

    • 第4章クイズ

      構造体ポインタと関数ポインタの理解を確認します。

    • qsortで並べ替える

      比較関数を書いて qsort で並べ替えられるようになります。

    • 関数ポインタ

      関数そのものを引数として渡せるようになります。

    • 動的な構造体配列

      構造体の一覧を動的な配列で持てるようになります。

    このレッスンに出てくる用語

    意味があいまいなまま進んだ語は、ここから読み直せます。

    • ヒープ親が子より常に大きい(最大ヒープ)または小さい(最小ヒープ)木構造。
    • 配列サイズ固定の同型データの集まり
    • 関数処理に名前を付けて再利用できる単位
    • グラフノード(頂点)とエッジ(辺)で構成されるデータ構造。
    • ループ繰り返し処理。矢印で戻すか専用記号で示す
    • 連結リスト各要素が次の要素へのポインタを持つ構造。
    • リスト順序付きで複数の値を扱うデータ構造
    main.c
    エディタを読み込んでいます

    メモ

    つくる 動的Student完成

    ⌘S で保存