はじめに
再帰関数の処理を見ているとなんでそうなる?!と理解に時間がかかったので知識の定着のために記事書いていきます
再帰関数とは
再帰関数とは、呼び出し元関数への復帰場所を記憶します。これは、問題を解決するために、自分の処理を繰り返し行うことを意味します。
<再帰関数の基本的な考え方>
再帰関数を使うときは、次の2つの要素が必要です:
1.再帰呼び出し
関数の中で、自分自身を呼び出します。
これにより、問題を小さな部分に分けて処理することができます。
2.終了条件
再帰呼び出しを終了するための条件を設定します。
終了条件がないと、関数が無限に呼び出され続けてしまいます。
再帰関数の例
void count(int n) {
if (n > 0) {
count(n - 1); // 自分自身を呼び出す
printf("%d\n", n); // 数字を表示する
}
}
count(3)
~ながれ~
1. count(3) の呼び出し
スタックに count(3) の状態が保存されます。
count(2) を呼び出します。
2.count(2) の呼び出し
スタックに count(2) の状態が保存されます。
count(1) を呼び出します。
3. count(1) の呼び出し
スタックに count(1) の状態が保存されます。
count(0) を呼び出します。
4.count(0) の呼び出し
スタックに count(0) の状態が保存されます。
count(0) の処理が終了し、スタックから count(0) の状態が取り出されます(つまり、count(0) が終了します)。
スタックから戻る
5.count(1) に戻る
count(0) が終了すると、スタックから count(0) の情報が取り出され、count(1) の実行が再開されます。
printf("%d\n", 1); が実行されます。
count(1) が終了すると、スタックから count(1) の情報が取り出され、count(2) の実行が再開されます。
6.count(2) に戻る
count(1) が終了すると、スタックから count(1) の情報が取り出され、count(2) の実行が再開されます。
printf("%d\n", 2); が実行されます。
count(2) が終了すると、スタックから count(2) の情報が取り出され、count(3) の実行が再開されます。
7.count(3) に戻る
count(2) が終了すると、スタックから count(2) の情報が取り出され、count(3) の実行が再開されます。
printf("%d\n", 3); が実行されます。
count(3) が終了し、全ての処理が完了します。
どういう仕組み?
まずこの解説をみたときに、戻るということはメモリをたどっていってるみたいな感じなのか?と思ったのですが正解でした。
スタックメモリが使用されているようです。
<再帰呼び出しの仕組み>
関数呼び出しでは、呼び出し元の「変数の値」と「実行位置」をスタックに保存します。これにより、どこまで処理が進んだかを記録できます。
再帰呼び出しでも、現在の状態をスタックに保存して再び自分自身の関数を呼び出すので、再帰呼び出し処理から戻ってきたときに正しく処理を続けることができます。
<スタックという仕組み>
プログラムが関数を呼び出すと、スタックという記憶場所に呼び出し元の状態(変数の値や実行位置)を保存し、その上に呼び出された関数で使用するローカル変数領域を確保します。
関数を呼び出すたびにスタックに情報が積み上がり、関数の処理が終わると最後に保存した呼び出し元の状態を復元します。
<スタックの役割>
スタックは、関数が呼び出されたときの状態(変数の値や実行位置など)を保存し、関数が終了するまでその状態を保持します。これにより、再帰呼び出しが終了した後に元の関数の処理を再開できるのです。
まとめ
とにかく難しいですが、細かくくだいていくと理解できました。実際に再帰関数を使用してコードを書く機会は少なさそうですが概念だけでもイメージできてよかったです