質問

これはばかげた質問のように聞こえるかもしれませんが、最後にプログラムしたのはアセンブラーでしたので、私の考えはずれているかもしれません:

そのような再帰関数:

def fac(n):
    if n == 0:
        return 1
    else:
        return n * fac(n - 1)

関数がn == 0に達したときに1を返さず、階乗である答えを返すのはなぜですか。アセンブラーでは、n == 0の場合のようになると考えています:

mov eax, 1
ret

上記のコードが機能する理由は、Pythonがその条件の前にスタックの最後の値を返すと思いますか?

役に立ちましたか?

解決

たとえば fac(5)の場合、次のように考えてください:

return 5 * fac(4)
           return 4 * fac(3)
                      return 3 * fac(2)
                                 return 2 * fac(1)
                                            return 1 * fac(0)
                                                       1

したがって、 1 first の戻り値になりますが、 fac(1)および fac(1)に返されます fac(2)などに返されます。

他のヒント

n == 0の場合、しない 1を返します。その戻り値は、呼び出し元サイトからスタックからポップされます。これは、 n * fac(n-1) 1 n を掛けて返されます。

fac(0)を呼び出すと、1が返されます(0ではなく、質問のタイプミスだと思います)。 fac(1)を呼び出すと、else節に入り、そこで fac(0)を呼び出します。これは1を返します。その後、n * 1(1)を計算し、それを返します。 fac(2)を呼び出すと、else節にも移動します。ここで、 fac(1)が呼び出され、上記のように1が返されるため、 n * fac(n-1)は2になり、それが fac(2)の戻り値になります。等々。それがあなたのために説明したことを願っています。

暗黙的に何も返されません-n = 0の場合、関数はifステートメントに入り、 return 1 ステートメントから直接1を返します。 ただし、これは「要因である回答」が表示される時点ではありません。ユーザーに返されます。代わりに、この値を n * fac(n-1)ブランチの途中にあるfac(1)によって呼び出される呼び出し関数。したがって、「1」を取得します。返され、 n * 1 を返します。これは、発信者に対して1です。それがfac(2)の場合、 n * 1 、または2をその発信者などに返します。

したがって、fac(5)は次のように翻訳されます:

fac(5) = 5 * fac(4) = 5 * (4 * fac(3) = 5 * (4* (3 * fac(2)) = 5 * (4* (3 * (2 * fac(1)) = 5 * (4* (3 * (2 * (1 * fac(0)) = 5*4*3*2*1*1

1つの値が各上位層を介して返された後にのみ、最初の呼び出し元に戻り、各段階での乗算により答えが得られます。

ジェームス、関数の最後の呼び出し(n == 0の場合)が返されるとき、それは呼び出しスタック上のfac(n)のいくつかのインスタンスの1つにすぎません。 print(fac(4))と言うと、スタックは本質的に次のようになります。

fac(0)
fac(1)
fac(2)
fac(3)
fac(4)
print()

fac(0)への最後の呼び出しは1を適切に返しますが、Pythonでは、fac(n)、fac(4)への最初の呼び出しの戻り値を要求しました。

「ret」が発生するループとは考えないでください。リターンは、保留中の実行の1つを単に終了します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top