작성
·
559
1
n=4가 되었을 때
이처럼 함수가 중첩된 상태라고 저는 이해했고, n=4가 되어 if문에 들어가지 않게 되자 원래 myfunc함수에서
if(n < 4)//stop condition
my_func(n + 1);
printf("Level %d, address of variable n = %p\n", n, &n);
이 부분에 있는 myfunc때문에 이 밑에 있는 printf("Level %d, address of variable n = %p\n", n, &n); 가 4번 실행 못한 상태가 되었기 때문에
지금 기준 20, 21번 줄을 반복하면서(처음에 중첩되면서 못 돈 부분들을 돌고 있음) myfunc함수가 myfunc안에 없었다면 이런일도 없었겠지만 안에 있는 myfunc함수 때문에 출력이 못된 부분들이 마지막에 순차적으로 나오는 것이라고 이해하면 될까요?
답변 1
1
안녕하세요, 답변 도우미 Soobak 입니다.
또 또 다시 뵙네요!! 반가워요!! 😀
네 재귀함수의 호출 순서에 대해서 잘 이해하고 계신 것 같습니다.
그럼에도 불구하고, 조금 더 부연 설명을 드려보겠습니다.
특히, 교수님의 이어지는 강의인 9.7 팩토리얼 예제 에서의 재귀 함수 예시를 활용하여 조금 자세히 설명드려보겠습니다. 해당 강의의 설명을 들어보시면 더 자세하게 이해하실 수 있으실 것 같아요. :)
음... 재귀함수는 함수 내부에서 자기 자신을 호출하는 함수라는 것은 이해하셨죠?
이 때, 함수 호출이 반복되면서 스택
에 쌓이게 되는데, 이 스택을 Call Stack, 호출 스택
이라고 하며, 함수가 호출 될 때마다 새로운 함수에 대한 데이터가 스택에 쌓이게 됩니다.
여기서, 스택
은 자료구조의 일종인데, LIFO, 후입선출
원칙에 따라 데이터를 저장하고 관리하며, 삽입과 삭제가 한 쪽 끝에서만 이루어진다는 특징을 갖는 자료구조입니다.
만약 스택 등의 자료구조에 대해 더 공부가 필요하시면 인터넷 검색, 혹은 무엇보다 홍정모 교수님께서 다양한 자료구조에 대해 설명해주시는 "따라하며 배우는 C언어 (부록)" 강의를 수강해보시는 것을 추천드립니다.
재귀함수를 이어서 설명드리면,스택
의 자료구조 특성 상, 재귀함수의 호출 순서는 호출 스택에 저장된 순서와 동일하게 됩니다.
말씀드렸던 대로, 교수님의 9.7 팩토리얼 예제 강의에서의 예시 코드로 설명드려보면,
long recursive_factorial(int n)
{
if (n > 0)
{
return n * recursive_factorial(n - 1);
}
else
return 1;
}
위와 같이 재귀함수를 통해 팩토리얼의 값을 계산하는 재귀함수가 있을 때,recursive_factorial(3)
을 호출한다면, 다음과 같은 과정을 따라 호출 스택에서 함수의 데이터가 생성/제거 됩니다.
첫 번째 호출: recursive_factorial(3)
현재 호출 스택: recursive_factorial(3)
-> recursive_factorial(3)
에서 recursive_factorial(2)
를 호출하고, 호출 스택에 추가됩니다.
두 번째 호출 : recursive_factorial(2)
현재 호출 스택: recursive_factorial(2)
, recursive_factorial(3)
-> recursive_factorial(2)
에서 recursive_factorial(1)
을 호출하고, 호출 스택에 추가됩니다.
세 번째 호출 : recursive_factorial(1)
현재 호출 스택 : recursive_factorial(1)
, recursive_factorial(2)
, recursive_factorial(3)
-> recursive_factorial(1)
에서 recursive_factorial(0)
을 호출하고, 호출 스택에 추가됩니다.
네 번째 호출 : recursive_factorial(0)
현재 호출 스택 : recursive_factorial(0)
, recursive_factorial(1)
, recursive_factorial(2)
, recursive_factorial(3)
-> recursive_factorial(0)
은 더 이상 재귀 호출을 진행하지 않으므로, 이전 호출에 대한 반환값을 반환한 후, 호출 스택에서 제거됩니다.
recursive_factorial(1) 으로 반환
현재 호출 스택 : recursive_factorial(1)
, recursive_factorial(2)
, recursive_factorial(3)
-> recursive_factorial(1)
에서 이전 호출에 대한 반환 값을 반환한 후, 호출 스택에서 제거됩니다.
recursive_factorial(2) 으로 반환
현재 호출 스택 : recursive_factorial(2)
, recursive_factorial(3)
-> recursive_factorial(2)
에서 이전 호출에 대한 반환 값을 반환한 후, 호출 스택에서 제거됩니다.
recursive_factorial(3) 으로 반환
현재 호출 스택 : recursive_factorial(3)
-> recursive_factorial(3)
에서 이전 호출에 대한 반환 값을 반환한 후, 호출 스택에서 제거됩니다.
따라서, 재귀함수의 호출 순서는 함수 호출 시 생성되는 함수의 데이터가 호출 스택에 저장되는 순서와 동일하며, 함수의 반환값이 계산되고 반환되면서, 저장된 순서의 역순으로 스택에서 제거됩니다.
또 궁금하신 점 있으시면 편하게 댓글 남겨주세요. 화이팅!
고맙습니다