정보처리기사 실기 프로그래밍 기출 C언어 재귀함수 문제 풀이
다음 C언어로 작성된 프로그램의 실행 결과에서 세 번째 줄에 출력되는 것은?
#include <stdio.h>
int func(int num) {
if (num == 1) {
return 1;
} else {
return num * func(num - 1);
}
}
int main() {
int i;
for (i = 5; i >= 0; i--) {
if (i % 2 == 1) {
printf("func(%d) : %d\n", i, func(i));
}
}
}
문제에서는 실행 결과 세 번째 줄에 출력되는 값을 묻고 있다.
main()
함수를 보면 for문의 i는 5, 4, 3, 2, 1의 범위 동안 2의 배수가 아닌 값일 경우 printf()
로 출력한다. 따라서 우리가 봐야할 건 5, 3, 1이다.
그런데 세 번째 줄에 출력이 된다는 건 1이 출력될 경우를 말하므로 1의 경우만 func()
함수를 타면 되겠다.
이 문제는 간단해서 func()
에 num
값으로 1이 들어갔을 때 바로 if문의 조건을 충족해서 1을 반환 받는다.
따라서 main()
함수의 printf("func(%d) : %d\n", i, func(i));
에 맞춰 출력값을 적어보자면 답안은 아래와 같다.
func(1) : 1
*문제의 답안과는 무관한 추가 해설임
재귀함수란?
- 함수 내에서 자신의 함수를 다시 호출하는 함수
- 스택 내에 쌓아두었다가 일괄 처리
위의 문제는 사실 재귀함수를 딱히 몰라도 답을 낼 수 있지만 재귀함수의 수행 방식을 알아보기 위해 위에서 printf()
로 출력 가능한 값이었던 5, 3, 1 중에 5를 예시로 func()
함수를 타보자.
func()
함수의 파라미터 num
에 5를 넣으면 if 조건문에서 num == 1
을 충족하지 못하므로 else 구문으로 넘어간다.
이때 return 값은 num * func(num - 1)
, 즉 5 * func(5 - 1)
이 된다.
재귀함수는 함수 내에서 자신을 다시 호출하는 함수다. 그리고 이는 스택에 쌓이다가 한 번에 처리된다. 이를 시각화해보면 다음과 같다.
num = 5 일 때의 스택이 쌓이고 이번에는 재귀함수의 호출로 인해 func(4)로 다시 func()
함수를 실행하게 된다.
num = 4로 해당 함수를 다시 돌면 return 값은 4 * func(4 - 1)
이 되고, 마찬가지로 func(4 - 1)
로 인해 함수로 재귀하게 된다.
이 과정은 return 값이 1이 되어 더 이상 재귀함수를 실행하지 않을 때까지 계속된다. num이 1이 되면 조건문에 의해 1을 반환하고 빠져나오기 때문이다.
이를 그림으로 나타내면 스택은 아래와 같이 쌓인다.
그리고 재귀 함수의 호출이 끝나면 일괄 처리되므로 맨 위의 상수값이 그 아래 스택 func()
의 num으로 전달되는 방식으로 연산이 이루어진다.
연산의 진행을 그림으로 나타내면 아래와 같다.
따라서, 만약 문제의 조건이 첫 번째 출력값을 출력하는 것이었다면 답은 func(5) : 120
이 되었을 것이다.
5를 입력받았을 때 출력 결과는?
#include <stdio.h>
int func(int a) {
if(a<=1) return 1;
return a*func(a-1);
}
int main(){
int a;
scanf("%d",&a);
printf("%d",func(a));
}
이 문제가 딱 위의 재귀함수 수행으로 결과값을 내는 경우이다.
scanf()
로 입력받은 5를 가지고 재귀함수 func()
으로 들어가면 위 문제에서 봤던 것과 동일한 방식으로 값들이 스택에 쌓인다.
따라서 답은 재귀함수를 마치고 나온 최종값 120이 된다.
120
#include <stdio.h>
int f(int n) {
if ( n > 0 ) {
return n % 10 + f( n / 10 );
} else {
return 0;
}
}
int main() {
int result;
result = f(123);
printf("%d\n", result);
}
일단 함수 return 값에서 자기 자신을 부르고 있다면 재귀함수다. f()
함수의 if문 return 값을 보면 f가 f를 호출하는 것을 확인할 수 있다.
따라서 이 리턴값들을 스택에 쌓을 생각으로 그려야 한다. 그릴 때는 해당 식을 그대로 넣지 말고, 바로 계산할 수 있도록 실제 값을 대입하면서 넣도록 한다.
main()
함수에서 f()
에 123을 넣어주고 있으므로 123을 n으로 넣어 식을 스택에 쌓아보자.
스택 맨 아래의 123 % 10 + f(12)
식은 다시 f(12)
를 부르므로 바로 다시 n = 12로 하여 연산식을 작성한다. 같은 방법으로 재귀함수를 빠져나올 때까지 진행한다.
재귀함수는 자기 자신을 빠져나와야 비로소 일괄 연산을 시작한다. 이제 위에서부터 순차적으로 값 0을 f()
에 대입하여 계산한다.
*정수와 정수의 계산값은 정수다.
따라서 최종 result 값은 6이 된다.
6
🙋🏻 참고한 곳
🔗 홍달쌤 유튜브 🔗 홍달쌤의 정보처리기사 실기 책