第29問

数値の並びを連結リスト(linked list)構造で表現し、その合計を求めるプログラムを作りました。プログラム中にwhileループが1つありますが、これをforループで置き換えたいと考えています。

どう書き直せばいいか、分かりますか?
main.c
#include <stdio.h>
#include <stdlib.h>

typedef struct ListNode {
  int value;
  struct ListNode *pNext;
} ListNode;

int SumListValues(const ListNode *pNode) {
  const ListNode *p = pNode;
  int sum = 0;

  while (p) {
    sum += p->value;
    p = p->pNext;
  }

  return sum;
}

int main(void) {
  ListNode node4 = { 40, 0 };
  ListNode node3 = { 30, &node4 };
  ListNode node2 = { 20, &node3 };
  ListNode node1 = { 10, &node2 };

  printf("Sum: %d\n", SumListValues(&node1));

  return EXIT_SUCCESS;
}
実行結果
Sum: 100
ここまでいろいろな問題を出してきたけど……
はい。
目的が同じプログラムでも、書き方は1つじゃないっていうことは分かったかしら?
もちろん!正解はいくつもあるってことですよね。
そのとおり!今回は、それをそのまま問題にしてみたわ。
えっと。つまり、別の正解を考えるってことですか?
そういうこと!……まず、連結リストは分かる?
たしか、「数珠つなぎ」になってるデータ構造だったと思います。
そうね。一つ一つの「数珠」にあたる部分を「ノード(node)」というのだけど……
あ、はい。プログラム中にありますね。
ここにノードが4つあって、それぞれに数値が入ってる……
  ListNode node4 = { 40, 0 };
  ListNode node3 = { 30, &node4 };
  ListNode node2 = { 20, &node3 };
  ListNode node1 = { 10, &node2 };
10203040っていう数値の並びになっているわね。
それって、node1node2node3node4の順番でつながってるってことですか?
そうよ。ノードの構造体を見れば分かると思うけど。
構造体は……これか。
typedef struct ListNode {
  int value;
  struct ListNode *pNext;
} ListNode;
数値をvalueに格納しつつ、pNextがポインタだから、これで次のノードにつながるんですね!
うん。そうやってできる「数珠つなぎ」が、連結リスト構造ね。
なるほど〜!
さてさて。ここまで分かったら、問題にとりかかれるんじゃないかしら?
おっと、そうでした。
whileが使われているのは、この関数か……
int SumListValues(const ListNode *pNode) {
  const ListNode *p = pNode;
  int sum = 0;

  while (p) {
    sum += p->value;
    p = p->pNext;
  }

  return sum;
}
このループをよく見て、forで書く場合の正解を考えてみてね。
はーい。やってみます!
ループの条件になっている変数に注目してみましょう!