![](/wp-content/include/images/avatar/teacher/6.png)
さあレオ君、いよいよ最後の問題よ!
![](/wp-content/include/images/avatar/student/12.png)
もう最後か〜。けっこう楽しかったのになぁ……
![](/wp-content/include/images/avatar/teacher/12.png)
あら、嬉しいことを言うじゃない。
![](/wp-content/include/images/avatar/student/8.png)
ユキ先輩のおかげで、僕もちょっとレベルアップできた気がします!
![](/wp-content/include/images/avatar/teacher/4.png)
よかったよかった。それじゃあラスト1問、はりきっていきましょうか!
![](/wp-content/include/images/avatar/student/3.png)
はーい!
以下は、第29問の答えのプログラムです。数値の並びを連結リスト(linked list)構造で表現し、その合計を関数SumListValues()
で求めています。この関数ではループが使われていますが、ループを使わない方法に置き換えたいと考えています。
![](/wp-content/include/images/avatar/teacher/5.png)
どう書き直せばいいか、分かりますか?
main.c
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode {
int value;
struct ListNode *pNext;
} ListNode;
int SumListValues(const ListNode *pNode) {
int sum = 0;
for (const ListNode *p = pNode; p; p = p->pNext) {
sum += p->value;
}
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
![](/wp-content/include/images/avatar/teacher/1.png)
第29問は正しいプログラムを、別の正しいプログラムに書き換える問題だったわよね。
![](/wp-content/include/images/avatar/student/5.png)
はい、そうでした。
![](/wp-content/include/images/avatar/teacher/6.png)
そこで、さらに別の方法で正しいプログラムを書いてみよう!っていうのが今回の問題よ。
![](/wp-content/include/images/avatar/student/7.png)
なるほど。でも、ループを使わない方法なんて、本当にあります?
![](/wp-content/include/images/avatar/teacher/3.png)
あるのよ。数値の並びは
10
、20
、30
、40
でしょう?
![](/wp-content/include/images/avatar/student/3.png)
はい。つまり、求めたいのは「
10
、20
、30
、40
の合計」ってことですよね。
![](/wp-content/include/images/avatar/teacher/5.png)
そうね。それを最初の1つと残りの3つを分けて考えたら、「
10
」と「20
、30
、40
の合計」の2つになるわよね。
![](/wp-content/include/images/avatar/student/2.png)
え……はい、なります。
![](/wp-content/include/images/avatar/teacher/3.png)
その2つを足したら、求めたい合計になるのよ。
![](/wp-content/include/images/avatar/student/11.png)
ええっ?それって解決になってます?
![](/wp-content/include/images/avatar/teacher/2.png)
あら、何かおかしなことを言ったかしら?
![](/wp-content/include/images/avatar/student/9.png)
だって、「
20
、30
、40
の合計」のほうは、結局ループしないと求められないですよ。
![](/wp-content/include/images/avatar/teacher/6.png)
そこはもう1回、最初の1つと残りを分けるのよ。
![](/wp-content/include/images/avatar/student/7.png)
ん?「
20
」と「30
、40
の合計」ってことですか?
![](/wp-content/include/images/avatar/teacher/3.png)
そう!そうやって2つに分ければ、足し算できるでしょ?
![](/wp-content/include/images/avatar/student/5.png)
あのー、何をどうすればいいのか、さっぱり分からないです……
![](/wp-content/include/images/avatar/teacher/4.png)
うん。ちょっと手応えがあったほうが最終問題っぽいでしょ。
![](/wp-content/include/images/avatar/student/4.png)
そ、そうですね……
![](/wp-content/include/images/avatar/teacher/1.png)
じゃあ、ヒントね。合計を求める関数には何を渡しているかしら?
![](/wp-content/include/images/avatar/student/7.png)
えっと、呼び出し元は
main()
関数にあって……ここだな。
printf("Sum: %d\n", SumListValues(&node1));
![](/wp-content/include/images/avatar/student/6.png)
引数として
node1
、つまり1つ目のノードのアドレスを渡してます。
![](/wp-content/include/images/avatar/teacher/5.png)
すると、1つ目以降の合計が分かるのよね。そこに2つ目のノードのアドレスを渡したらどうなるかしら?
![](/wp-content/include/images/avatar/student/7.png)
それって、こういうこと?
printf("Sum: %d\n", SumListValues(&node2));
![](/wp-content/include/images/avatar/student/11.png)
そっか。この場合は2つ目以降の合計になるんですね!
![](/wp-content/include/images/avatar/teacher/3.png)
そういうこと。だんだん答えに近付いてきたんじゃない?
![](/wp-content/include/images/avatar/student/7.png)
そうなんですか?もうちょっと考えてみます!
![](/wp-content/include/images/avatar/teacher/7.png)
この関数から自分自身を呼び出すようにすれば……