인프런 커뮤니티 질문&답변

Organ님의 프로필 이미지
Organ

작성한 질문수

홍정모의 따라하며 배우는 C언어

9.7 재귀 호출과 스택

재귀호출 질문입니다

작성

·

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) 을 호출한다면, 다음과 같은 과정을 따라 호출 스택에서 함수의 데이터가 생성/제거 됩니다.

  1. 첫 번째 호출: recursive_factorial(3)

    • 현재 호출 스택: recursive_factorial(3)

      -> recursive_factorial(3) 에서 recursive_factorial(2) 를 호출하고, 호출 스택에 추가됩니다.

  2. 두 번째 호출 : recursive_factorial(2)

    • 현재 호출 스택: recursive_factorial(2), recursive_factorial(3)

      -> recursive_factorial(2) 에서 recursive_factorial(1) 을 호출하고, 호출 스택에 추가됩니다.

  3. 세 번째 호출 : recursive_factorial(1)

    • 현재 호출 스택 : recursive_factorial(1), recursive_factorial(2), recursive_factorial(3)

      -> recursive_factorial(1) 에서 recursive_factorial(0) 을 호출하고, 호출 스택에 추가됩니다.

  4. 네 번째 호출 : recursive_factorial(0)

    • 현재 호출 스택 : recursive_factorial(0), recursive_factorial(1), recursive_factorial(2), recursive_factorial(3)

      -> recursive_factorial(0)더 이상 재귀 호출을 진행하지 않으므로, 이전 호출에 대한 반환값을 반환한 후, 호출 스택에서 제거됩니다.

  5. recursive_factorial(1) 으로 반환

    • 현재 호출 스택 : recursive_factorial(1), recursive_factorial(2), recursive_factorial(3)

      -> recursive_factorial(1) 에서 이전 호출에 대한 반환 값을 반환한 후, 호출 스택에서 제거됩니다.

  6. recursive_factorial(2) 으로 반환

    • 현재 호출 스택 : recursive_factorial(2), recursive_factorial(3)

      -> recursive_factorial(2) 에서 이전 호출에 대한 반환 값을 반환한 후, 호출 스택에서 제거됩니다.

  7. recursive_factorial(3) 으로 반환

    • 현재 호출 스택 : recursive_factorial(3)

      -> recursive_factorial(3) 에서 이전 호출에 대한 반환 값을 반환한 후, 호출 스택에서 제거됩니다.

따라서, 재귀함수의 호출 순서는 함수 호출 시 생성되는 함수의 데이터가 호출 스택에 저장되는 순서와 동일하며, 함수의 반환값이 계산되고 반환되면서, 저장된 순서의 역순으로 스택에서 제거됩니다.

또 궁금하신 점 있으시면 편하게 댓글 남겨주세요. 화이팅!

Organ님의 프로필 이미지
Organ
질문자

고맙습니다

Organ님의 프로필 이미지
Organ

작성한 질문수

질문하기