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

    リストを歩く

    何番目、では取り出せない

    前回で追加ができるようになりました。今度は中身を全部見る番です。

    配列なら for (i = 0; i < n; i++) で list[i] を順に見ました。リストにはその添字がありません。2人目がどこにいるかは、1人目の next を読むまで分からないからです。ノードは malloc が空いている場所へ置いていくので、番地の並びと順番は無関係です。並び順を持っているのは矢印だけです。

    歩く形はいつも同じ

    そこで、ポインタを1本用意して、矢印をたどって進めます。

    c

    struct Node *p;
    for (p = head; p != NULL; p = p->next) {
        printf("%s %d点\n", p->name, p->score);
    }

    初期化が p = head、続ける条件が p != NULL、更新が p = p->next です。この3つは配列の i = 0 と i < n と i++ にそのまま対応します。リストを歩くコードはほぼ全部この形になるので、指の形として覚えてしまってよいところです。

    止まる条件が p != NULL になるのは、最後のノードの next に NULL を入れてあるからです。終端の印を決めておいたことが、ここで効きます。

    head そのものを動かさない

    やりがちな間違いは、作業用のポインタを用意せずに head を進めてしまうことです。

    c

    while (head != NULL) {
        printf("%s\n", head->name);
        head = head->next;   /* 呼び出し元の先頭が失われる */
    }

    関数の引数として受け取った head なら、動かしても写しなので呼び出し元は無事です。しかし同じ癖で main の head を進めると、表示が終わったときリストの先頭がどこにも残っておらず、全ノードが解放できないまま迷子になります。歩くときは必ず別のポインタを使う、と決めておくと安全です。

    数えるのも足すのも同じ歩き方

    人数を数える、点数を合計する、特定の名前を探す。どれも歩き方は同じで、ループの中で何をするかが違うだけです。探索の場合は見つけた時点で return p; すれば途中で止められます。

    歩く回数は積み上がる

    気をつけたいのは、歩くこと自体は人数に比例した手間だという点です。表示のたびに人数を数え直し、合計も数え直し、その中でまた探索を呼ぶ、という書き方をすると、1回の操作で何度もリスト全体を往復します。人数が少ないうちは気づきませんが、これは配列で詰め直しをしていたときと同じ種類の重さです。

    対策は難しくありません。1回の歩きで済むものは1回にまとめる、人数のように変化が分かっているものは追加と削除のときに増減させて持っておく、といった程度です。今回は素直に別々の関数として書きますが、「この関数は先頭から終端まで1往復する」という感覚は持っておいてください。

    では、一覧表示と合計点の2つを、同じ歩き方で書いてみましょう。

    要件

    1. 作業用のポインタを用意して歩く
    2. 終端の判定は NULL と比べる
    3. print_list は1人1行で表示する
    4. total_score は合計を戻り値で返す

    ヒント

    for (p = head; p != NULL; p = p->next) が歩く定型です

    1人もいないときはループが1回も回らず、合計は0のままになります

    先頭追加なので、表示は入力の逆順になります

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

    関連レッスン

    • 任意位置の挿入と削除

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

    • リストを全解放する

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

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

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

    • 第5章クイズ

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

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

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

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

    メモ

    リストを歩く

    ⌘S で保存