コース一覧
    C言語中級 連結リスト・応用
    つくる リスト版成績管理

    C言語中級 連結リスト・応用

    C言語の連結リストと応用的なデータ操作を学び、実装でデータを扱うコースです。

    1
    連結リスト
    01. 配列の限界15分
    02. ノードを定義する15分
    03. 先頭に追加する15分
    04. リストを歩く15分
    05. 任意位置の挿入と削除15分
    06. リストを全解放する15分
    07. つくる リスト版成績管理15分
    08. 第5章クイズ10分
    2
    応用
    01. 動的な二次元配列15分
    02. コマンドライン引数15分
    03. バイナリ保存15分
    04. エラーの調べ方15分
    05. つくる 引数とバイナリ保存15分
    06. 第6章クイズ10分
    3
    総合制作
    01. リスト版を完成させる20分
    02. メモリバグ演習20分
    03. 自由拡張20分
    04. 完成と次のステップ10分

    つくる リスト版成績管理

    部品はそろった

    この章で、追加、走査、挿入、削除、全解放を1つずつ書いてきました。今回はそれを1本の成績管理としてまとめます。作るのは、標準入力からコマンドを読んで動くプログラムです。

    扱うコマンドは4つです。ADD 名前 点数 で追加、DEL 名前 で削除、LIST で一覧と合計、END で全解放して終了します。

    配列版と何が変わったか

    入門で作った配列版には struct Student list[10] のような上限がありました。11人目を入れようとしたら、上限を上げてコンパイルし直すか、入力を断るしかありません。リスト版に上限はありません。人数の上限は、malloc が失敗する日まで来ません。

    削除の中身も変わりました。配列版は後ろ全員を1つずつ前へ詰め直していました。リスト版は矢印1本の付け替えと free 1回です。人数が増えても削除の手間は変わりません。

    代わりに手放したものもあります。何番目、で一発で取り出すことはできなくなりました。この章の題材では、一覧と出し入れが中心で番号で引く場面が無いので、割の良い交換になっています。

    状態は head 1本に集まる

    配列版では、配列と人数の2つを常に揃えて持ち歩く必要がありました。片方だけ更新して食い違うのが定番の不具合です。リスト版で持つのは head だけで、人数は歩けば分かります。持つ状態が減ると、食い違いようがなくなります。

    その代わり head は追加や削除で変わるので、これらの関数は新しい先頭を返し、呼び出し側で必ず受け直します。

    c

    head = insert_head(head, name, score);
    head = delete_by_name(head, name);

    受け直しを1か所忘れるだけでリストが壊れるので、head を書き替える可能性のある関数は同じ形にそろえておくと間違えにくくなります。

    見つからないときの扱いを決めておく

    DEL で指定した名前がいないことは、異常ではなく普通に起きます。黙って何も起きないと、使う側は消えたのか消えていないのか分かりません。今回は、削除の前に探して、いなければその旨を表示することにします。LIST も同じで、1人もいないときは空行ではなく、いないことを表示します。

    終わりに必ず片付ける

    END では free_list を呼んで、解放した個数を表示します。個数が追加した人数と合わないなら、どこかで矢印を切ってしまい、たどり着けないノードを作ったということです。この数字は、そのままリークの検査になります。

    削除の前に探す形にしておく理由

    delete_by_name は、見つからないときに何もせず head を返します。呼び出し側から見ると、成功しても失敗しても戻り値は head なので、どちらだったのか区別が付きません。今回は先に find_node で探し、その結果で表示を分けます。関数を1つ増やす代わりに、削除の関数を「消す」だけの役目に保てます。成功したかどうかも返す設計にすると、戻り値が新しい先頭なのか成否なのかで悩むことになります。役目を1つに絞っておくほうが、あとから読んで迷いません。

    では、コマンドを読んで振り分ける部分を書きましょう。関数はすべて用意してあります。

    要件

    1. コマンドは ADD、DEL、LIST、END の4つを扱う
    2. ADD のあとには名前と点数が続く
    3. DEL は先に find_node で探し、いない場合は見つからない旨を表示する
    4. LIST は空のとき「0人です」とだけ表示する
    5. END では free_list の戻り値を使って個数を表示し、ループを抜ける

    ヒント

    コマンドの判定は strcmp が 0 を返すかどうかで行います

    insert_head と delete_by_name の戻り値は head に受け直します

    追加や削除のたびに数え直さなくても、LIST のときに count_list を呼べば足ります

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

    関連レッスン

    • 第5章クイズ

      連結リストの操作とつなぎ替えの理解を確認します。

    • 動的な二次元配列

      ポインタのポインタで表形式のデータを確保できるようになります。

    • リスト版を完成させる

      全機能をリスト前提で1本にまとめられるようになります。

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

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

    • 配列サイズ固定の同型データの集まり
    • コンパイルソースをバイトコードへ変換する処理
    • リスト順序付きで複数の値を扱うデータ構造
    • 関数処理に名前を付けて再利用できる単位
    • 戻り値呼び出し元への返答を表す点線矢印
    • 設計何をどう作るかを決める前工程
    • ループ繰り返し処理。矢印で戻すか専用記号で示す
    main.c
    エディタを読み込んでいます

    メモ

    つくる リスト版成績管理

    ⌘S で保存