2016-09-26 11 views
0

私はprint_backward関数コードをオンラインにしましたが、それはどのように動作し、その出力については非常に混乱しています 。Python再帰関数に関する混乱

以下は私のコードです。

def print_backward(num): 
    if num == 10: 
     return 
    num += 1 
    print(num) 
    print_backward(num) 
    print("yeah") 
    print(num) 
    print() 

print_backward(6) 

以下が出力されます。

7 
8 
9 
10 
yeah 
10 

yeah 
9 

yeah 
8 

yeah 
7 

私はそれはそれは+ = 1

しかし、numが10を達成したら、私は、混乱午前、print_backwardべき リターンNUM、再帰的に を呼び出すたび以来、7から10に出力する方法を理解することができます、その後、完了しました。それは、ええええええええええええええええええええええええええええ、まあいいえ、ああ 7.なぜこのコードは、それはまだ印刷することができますどのように返されたと呼ばれている?このコードがどのように後方に印刷するのか、つまりprint(num)と呼ばれる理由は、 は10から7まで印刷できますか?最初の実行で

答えて

0

、コードはさらにprint_backward(num)に内部の呼び出しよりも行かない、それは引数が10に達した場合(無限再帰のように)4回

、すべての機能が戻り、それがさらに進んでいます元のnum +1を印刷していました。

数値が高いコールが最初に返されるため、最も高い番号が最初に印刷されます。

+0

ありがとうございました。それは非常に明確です。 – OregonDuck

+0

本当にありがとうございます。 – OregonDuck

+1

問題ありません!これらの再帰呼び出しはあまり直感的ではありません。デバッガを使用すると、ときどき助けになります。 –

0

スタックを介して関数呼び出しが行われます。

6でprint_backwardを呼び出します。スタックには6があります。
これで7と呼ばれます--->スタックには6,7があり、7がトップです。
これを8 ---->と呼びます。スタックは6,7,8です。
今度は9になりますので、スタックは6,7,8,9です。
今度は10でスタックは6,7で、 8,9,10。

関数が戻ると、スタックからポップします。
あなたはパラメータ10で機能していたので、returnを呼び出してスタックからポップしました。スタックは6,7,8,9です。
これは "ええ"と10を出力します(numは9で、前にnum = num + 1としたため)。 今戻ってポップします。9.スタックは6,7,8
です。これで、numが8でnum = num +1したので、9が表示されます。

同様に、他のものも印刷します。

+0

ありがとうございました。スタックは、このコードがどのように動作するかを理解するのに良いことです。本当にあなたの時間を感謝します。 – OregonDuck

+0

@OregonDuck:問題ありません –

1

実際には、関数呼び出しはスタック操作です。また、再帰は関数呼び出しの特殊なケースです。

関数を呼び出すたびに、リターンアドレスがスタックにプッシュされ、関数がリターンすると、プログラムはスタックの先頭からリターンアドレスをポップし、そこからプログラムを実行し続けます。 call stackについての公式の説明をwikipediaに見ることができます。

たとえば、print_backward(7)が最初にコールされ、次のコマンドがスタックにプッシュされ、print_backward(8)を呼び出すと、次のコマンドが再びスタックにプッシュされるので、4回の再帰呼び出しの後にスタックこのようになります:

+-------------------------+ <--- Stack top 
| num = 10, print("yeah") | \ 
| num = 9, print("yeah") | | 
| num = 8, print("yeah") | > Call stack 
| num = 7, print("yeah") | | 
+-------------------------+/

基準が条件num == 10:print_backward(10)から呼び出す場合を打ちます。プログラムはreturnステートメントを実行し、スタックトップからReturn addressがポップし、そこからプログラムが開始されます。つまり、num = 10の場合はprint('yeah')が実行されます。 print_backward(10)の呼び出しが完了すると、スタックはスタックから別の戻りアドレスをポップし、print('yeah')print_backward(9)に実行します。この操作は、スタックが空のときに終了します。つまり、関数の戻り値がなくなります。あなたのケースでは

+0

優秀な説明。どうもありがとうございます。非常に詳細、超クリア。 – OregonDuck

+0

本当にありがとうございます。 – OregonDuck

+0

お互いから学ぶ...。 – Enix

0

- print_backward(6)if num == 10、すなわちそれは、リターン基準をヒットする4つのコール(再帰的に)を取った - 関数が印刷されたこれらの呼び出し時に:

7 # print_backward(6) - first call we made 
8 # print_backward(7) - recursive 
9 # print_backward(8) - recursive 
10 # print_backward(9) - recursive - inner most, where the return is executed 

を次の再帰呼び出しprint_backward(10)ための復帰条件が真取得し、再帰呼び出し(ライン6)以下の行を結果として

yeah # 4th call (inner most) returned 
10 

yeah # 3rd call returned 
9 

yeah # 2nd call returned 
8 

yeah # 1st call returned 
7 

コールスタックビューの可視化、すなわち、呼び出される - この関数は(最も内側の呼び出しから始まる)の復帰を開始します「がをd:

print_backward(6) 
| 7 # num += 1 and then print(num) 
| print_backward(7) 
| | 8 
| | print_backward(8) 
| | | 9 
| | | print_backward(9) 
| | | | 10 
| | | | | print_backward(10) 
| | | | | | return 
| | | | yeah # print("yeah") 
| | | | 10 # print(num) 
| | | |() # print() 
| | | yeah 
| | | 9 
| | |() 
| | yeah 
| | 8 
| |() 
| yeah 
| 7 
|() 
+0

私の質問には素晴らしいグラフと答えです。それは私のコードのプロセスをよく知っています。本当にありがとう、ありがとう。本当に役に立ちます。本当にあなたの時間を感謝します。 – OregonDuck

0

(6)

1 check for 10 
2 increase 6 by one num = 7 
3 print 7 
4 call backward with 7 

6 print_backwardがまだ完了していないとprint_backward(7)スタックの一番上にプッシュされ、次に呼び出されたときにprint_backward。残りの部分

print("yeah") 
print(7) 

最後に再帰呼び出しが完了すると実行されます。私は以下のステップで小切手10をスキップしています。最後のステップでそれを含めるでしょう。

5 increase 7 by one num = 8 
6 print 8 
7 call backward with 8 (7 not completed) 
8 increase 8 by one num = 9 
9 print 9 
10 call backward with 9 (8 not completed) 
11 increase 9 by one num = 10 
12 print 10 
return is encountered 
13 call backward with 10 (9 not completed) 
14 check for 10 and return. 9 will continue for the execution. 
15 in the execution of 9 num is 10 so yeah is printed and then 10 is printed and print_backward for 9 is completed. Similarly for 8 num is 9 which print yeah followed by 9 and so on. 
+0

良い説明。ステップバイステップで、非常に理解しやすく理解しやすい。どうもありがとうございます。私は再帰について深く理解していると信じています。本当にあなたの助けと時間を感謝します。 – OregonDuck