質問: f(5); Console.ReadKey(); } ```
回答: 理解にお困りの`return`文が返す値を計算している式を見ると、 `f(i - 1) + i`という計算を行っていることはお解り頂けると思います。 これを、説明の都合上、`j`, `k`という整数変数を使って書き直すと、 ``` int j = i - 1; // 引き算 int k = f(j); // 関数呼び出し return k + i; // 足し算の結果をリターン ``` と、いう風に書き直せます。 確かに四則演算には優先順位があり、優先順位を表現上やむを得なく変更するために`()`を使ってその中に記述された部分式を優先的に計算するというルールはありますが、もう一つ、 > > 関数呼び出しを含む計算式は、関数呼び出しが優先され、呼ばれた関数の計算結果が帰ってくるまで式の計算は据え置かれる > > > というルールがあるというか、そういう振る舞いをします(あたり前の事なんですが)。 それを踏まえて上のプログラムがどう動くか追ってみると、 (説明の都合上`f()`が呼ばれる度に文字が一つインデントが深くなると思ってください) ``` f(5)を計算するためには、f(5 - 1)を計算する(呼ぶ) f(5 - 1) つまり f(4)を呼ぶ f(4 - 1) つまり f(3)を呼ぶ f(3 - 1) つまり f(2)を呼ぶ f(2 - 1) つまり f(1)を呼ぶ f(1 - 1) つまり f(0)を呼ぶ f(0) は 0 を返す f(0) が 0 を返したので 0 + 1 (=1) を返す f(1) が 1 を返したので 1 + 2 (=3)を返す f(2) が 3 を返したので 3 + 3 (=6)を返す f(3) が 6 を返したので 6 + 4 (=10)を返す f(4) が 10 を返したので 10 + 5 (=15)を返す ``` 今回の問題点は関数を`f()`というどんな処理をするかわからない上に短い関数名にしてしまったため、関数呼び出しの引数を指定するための`()`と四則演算の優先順位を意図的に変更する`()`を取り違えたのも原因だと思います。 上の振る舞いを見ると、0から引数までの総和を求める関数の様なので、僕でしたら、 ``` int f(int i) ``` というなにをしたいのかわからない名前ではなく ``` int sumOfZeroTo(int i) ``` の様な関数名にしたと思います。 この様に`for`や`while`などのループを使わずに、関数`f()`の中で自分自身(関数`f()`)を呼ぶことで目的の計算結果を得る手法が当初の質問タイトルにあった**再帰**と呼ばれる手法ですが、脱出条件を間違えると簡単に無限ループになるなどデメリットもそれなりなので、手法として覚えておくだけで、ループで済む計算ならループで処理してしまった方が、ビギナーにはバグを作り込むリスクを減らせて良いと僕は思います。 最後になりますが、matsuzawaさんは言語の「ある機能」の確認のためのコード素片を書いてプログラム言語の勉強をされているようですが、そろそろ数百行規模のプログラムを書いてみて、それに必要な機能は何で、それはどうやって記述すれば良いのだろうか?という勉強方法に切り替えて行かれた方が良い気がします。 プログラムは、「やりたいこと」があって、それをどういう手続きに分割すれば出来るか?(大まかな抽象化)した関数やクラス の中ででは、それは具体的には何をすれば良いのか?・・・と言うことを繰り返して行く作業ですが、今の勉強方法では、言語の機能は覚えられても、やりたいこと(例えばこういう入力から、こういう出力を得たい)というプログラム全体の流れを(徐々に)細分化してやりたいことをプログラムを書き、動かすことで達成するという勉強が出来ないと思います。 言語の機能を覚えるだけでプログラムを書きたいわけではないのでしたら今のままで構わないと思いますが、プログラミングというのは「手段」であって、「目的」は「プログラムを作る(書く)ことで、処理させたいことが何度行っても間違い無く行える様になる」事だと思います。この点を頭の片隅にでも留め置きながら今後の勉強をされること良いのではないかと思います。