Re: recursion vs loop
久野です。
hata@iname.comさん:
> ただ、この場合の両者の違いとして、while ループは外側に関数(ループ内の
> ルーチン)の呼出が並べられて展開されるが、再帰呼出は内側に入れ子状に関数
> の呼出が展開される、というようなイメージでいいのでしょうか?
それは何の話? 計算モデル? 実装?
計算モデル的には「埋め込まれる」と考えてもいいんでしょうけど、
実装上は関数は「戻り番地と引数をスタックに積んでジャンプし、内部
を実行し、戻る時はスタックから戻り番地を取り降ろして戻る」という
形になります。
> という風に階乗の計算と代入が逐次的に行われていくイメージがありますが、
> 再帰呼出だと、
> n! = n * (n - 1)!
> n! = n * (n - 1) * (n - 2)!
> (……)
> n! = n * (n - 1) * (n - 2)! * (……) * 2 * 1
それで正しいですね。
5!
5 * 4!
5 * 4 * 3!
5 * 4 * 3 * 2!
5 * 4 * 3 * 2 * 1!
5 * 4 * 3 * 2 * 1 * 0!
5 * 4 * 3 * 2 * 1 * 1
5 * 4 * 3 * 2 * 1
5 * 4 * 3 * 2
5 * 4 * 6
5 * 24
120
> 処理系(ちなみに自分が親しんでいる言語は Perl です)によって違いがあるの
> かもしれませんが、同じことをやるのなら、while ループの方が効率は良さそう
> な気がします(それに再帰の場合はコンパイラ側のスタック(?)の管理が大変
> そうに思える)が、実際のところどうなのでしょう?
別に大変じゃないです。単にそういうコード出せばいいだけだから。
人間が実装を追うのが面倒なだけで。 久野
P.S. そして最適化によってスタックを使わずにwhileと同等に計算する
ようなコンパイラもあると思う。
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735