コース一覧
    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分

    先頭に追加する

    先頭は、動かすものが無い場所

    前回はノードを手で2つ作ってつなぎました。今回はそれを関数にして、何人でも足せるようにします。足す場所は先頭にします。

    先頭を選ぶのは手抜きではありません。配列で先頭に入れるのが一番重かったのを思い出してください。リストでは逆に、先頭がいちばん軽い場所です。前のノードを探す必要がなく、動かす要素も無く、書き替えるのは矢印2本だけだからです。

    空のリストは NULL

    リスト全体は、先頭のノードを指すポインタ1本で表します。この変数をふつう head と呼びます。

    1人もいない状態は head == NULL です。空のリストのために特別な入れ物を用意しないところが大事で、おかげで「1人もいないとき」と「1人以上いるとき」を同じコードで扱えます。

    つなぐ順番を間違えない

    追加は次の2行です。

    c

    node->next = head;
    head = node;

    必ずこの順です。先に head = node; としてしまうと、元の先頭を指していた値がどこにも残らず、そのあと node->next = head; と書けば自分自身を指してしまいます。こうなると2人目以降が丸ごと迷子になり、しかもリストを歩くと永久に終わりません。

    head を書き替えるので、戻り値で返す

    追加を関数にすると、先頭が変わるという点が引っかかります。

    c

    struct Node *insert_head(struct Node *head, const char *name, int score);

    head を引数で受け取っても、それは呼び出し元の変数の写しなので、関数の中で入れ替えても呼び出し元には伝わりません。入門でポインタ渡しを見たときと同じ話です。

    やり方は2つあります。新しい先頭を戻り値で返して呼び出し元で受け直す形と、struct Node ** を受け取って呼び出し元の変数そのものを書き替える形です。この章では読みやすい前者で通します。呼び出し側はこうなります。

    c

    head = insert_head(head, "田中", 82);

    代入を忘れると追加が消えるので、そこだけ気をつけます。

    確保に失敗したとき

    malloc が NULL を返したら、ノードは作れていません。そのときは元の head をそのまま返して、リストを壊さずに諦めます。

    名前は箱ごとコピーする

    ノードの name は char[32] の配列です。受け取った const char *name をそのまま node->name = name; とは書けませんし、書けたとしてもやりたいこととは違います。呼び出し元の文字列を指すだけになるので、その文字列が次の読み込みで上書きされた瞬間、リストの中の名前まで変わってしまうからです。

    c

    strncpy(node->name, name, 31);
    node->name[31] = '\0';

    strncpy は上限を超えると終端の 0 を置いてくれないので、最後の1文字を自分で入れておきます。ノードは自分の名前を自分の中に持つ、という形にしておけば、元の文字列がどうなろうとリストは無事です。

    では、3人を順に先頭追加してみましょう。読み込んだ順と表示される順が逆になるはずです。

    要件

    1. malloc でノード1個分を確保する
    2. 確保に失敗したら元の head をそのまま返す
    3. name は文字列としてコピーし、score は代入で入れる
    4. 新しいノードの next を元の先頭に向けてから、そのノードを返す

    ヒント

    先に head を書き替える必要はありません。返す値が新しい先頭になります

    name は配列なので = ではコピーできません。strncpy などを使い、終端の 0 を必ず入れます

    3人を先頭に足していくので、表示は入力の逆順になります

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

    関連レッスン

    • リストを歩く

      終端まで順にたどれるようになります。

    • 任意位置の挿入と削除

      前のノードをつなぎ替えて、途中の要素を出し入れできるようになります。

    • リストを全解放する

      順序を守って最後まで解放できるようになります。

    • つくる リスト版成績管理

      配列版の成績管理をリスト版に移行できるようになります。

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

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

    • 関数処理に名前を付けて再利用できる単位
    • 配列サイズ固定の同型データの集まり
    • リスト順序付きで複数の値を扱うデータ構造
    • 変数データに名前をつけて参照する仕組み
    • 戻り値呼び出し元への返答を表す点線矢印
    • 引数位置引数=順番で渡す。
    main.c
    エディタを読み込んでいます

    メモ

    先頭に追加する

    ⌘S で保存