2016-09-26 2 views
0

나는 print_backward 함수 코드를 온라인으로 받았지만, 나는 그게 어떻게 작동하는지 그리고 그 출력에 대해서는 매우 혼란 스럽다. .파이썬 재귀 함수에 대한 혼동

아래 코드는 제 코드입니다.

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 인쇄하는 방법을 이해할 수있다 , 그 다음에 끝났다. 그것은 인쇄하지 말아야합니다 10, 예 9, 예 8, 예 7. 왜이 코드가 반환을 호출했는지, 어떻게 여전히 인쇄 할 수 있습니까? 이 코드가 뒤로 인쇄하는 방법, 즉 print(num)을 호출 한 이유는 무엇입니까? 은 10에서 7까지 인쇄 할 수 있습니까? 첫 번째 실행에

답변

0

print_backward(num)에 내부 통화보다 더하지 않는 코드, 즉 (무한 재귀 같은) 4 회

인수가 10에 도달

는 모든 기능이 반환이며 더 나아가 원래의 num +1을 인쇄했습니다.

숫자가 더 높은 번호의 전화가 먼저 오기 때문에 가장 높은 번호가 먼저 인쇄됩니다.

+0

설명해 주셔서 감사합니다. 그것은 아주 분명하다. – OregonDuck

+0

정말 고맙습니다. – OregonDuck

+1

괜찮습니다! 이러한 재귀 호출은 매우 직관적이지 않습니다. 디버거를 사용하면 가끔 도움이 될 수 있습니다. –

0

함수 호출은 스택을 통해 발생합니다.

6에서 print_backward를 호출합니다. 따라서 스택에 6이 있습니다.
이제 이것을 7에서 호출합니다. ---> 따라서 스택에는 6,7이 있으며 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와 9를 출력합니다.

마찬가지로 기타도 인쇄합니다.

+0

고마워요. 스택은이 코드의 작동 방식을 이해하는 데 도움이됩니다. 정말로 시간을 내 주셔서 감사합니다. – OregonDuck

+0

@OregonDuck : 문제 없음 –

1

함수 호출은 실제로 스택 연산입니다. 그리고 재귀는 함수 호출의 특별한 경우입니다.

함수를 호출 할 때마다 Return Address가 스택으로 푸시되고 함수가 돌아 오면 프로그램은 스택 상단의 Return 주소를 표시하고 거기에서 프로그램이 계속 실행됩니다. 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)에 대한 호출이 완료되면 스택에서 스택의 다른 Return Address가 스택에 나타나고 print('yeah')print_backward(9)에 실행됩니다. 이 작업은 스택이 비어있을 때 종료됩니다. 즉, 더 이상 함수가 반환되지 않습니다. 귀하의 경우를 들어

+0

우수 설명. 고마워, 친구. 매우 상세하고, 매우 깨끗합니다. – OregonDuck

+0

정말 감사드립니다. – OregonDuck

+0

서로에게서 배울, 하하 ... – Enix

0

는 - print_backward(6)는 반환 기준 if num == 10을 즉, 칠 (재귀 적으로) 4 전화를했다 - 그 통화 중 기능 인쇄 : 다음 재귀 호출 print_backward(10)를 들어

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 

반환 조건은 진정한 도착하고, 재귀 호출 (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