한번도 사용하지 않은 사람은 있어도 한번만 사용한 사람은
없다는 이 재귀호출, 사실 컴퓨터 언어입장에서는 재귀호출,
일반호출의 동작원리는 차이가 없다. 다만,인간의 뇌는 컴퓨터와
같은 메모리 구조가 아니기 때문에 좀더 이해하기 어렵다는 것이다.
재귀호출은 특정 조건을 만족할때 까지 자기자신을 계속 호출하는
함수다.이것이 핵심이다.
일반함수
1부터 10까지 더하는 함수를 만들어 보자
루프 함수를 이용해서 1부터 10까지 더하는 함수 이다.
for loop의 비교 조건 까지 루프가 진행이 된다.
void loop_sum()
{
int sum = 0;
for (int i = 1; i <= 10; i++)
{
sum = sum + i;
}
printf("Total Sum:%d\n", sum);
}
재귀 함수 패턴
재귀 함수는 전형적인 패턴을 가지고 있으며,해당 패턴안에 필요한
로직을 구현하는 형태로 코드가 작성이 된다.
재귀함수는 조건을 만족할때 까지 자기자신을 호출하는 가장 기본적인 구조이다.
return_type function_name(type p1...) {
//재귀 호출 탈출 조건 변수 선언
bool escape_condition = false;
//내부 로직에 필요한 데이터 선언부...
//재귀 호출 탈출 조건 체크
//지금은 임의로 p1이 0일 경우로 되어 있지만
//로직에 따라 escape_condition을 true로
//만드는 코드는 틀려질 수 있다.
if (p1 == 0)
{
escape_condition = true;
}
//탈출 조건이면 return을 통해 함수 종료
//return 값은 로직에 따라 틀려질수 있음
if (escape_condition == true)
{
printf("Escape Recursive Call\n");
return xxx;
}
//탈출 조건이 아니면 계속 해서 호출
else {
rr_sum(p-1);
}
//탈출 조건을 통해 이전 호출이 return되면
//아래 return문을 수행하면서 호출한 함수들도
//순차적으로 return이 발생.
return sum;
}
일반 함수를 재귀함수로 만들기
2번의 재귀 함수 패턴을 사용하여 1번의 sum함수를
재귀함수 형태로 작성하면 다음과 같다.
리턴타입 : int (1부터 10까지 정수의 합)
함수이름 : rr_sum
그리고 계속해서 자신을 호출하면서 숫자를 로직을 추가하면 된다.
int rr_sum(int p1) {
bool escape_condition = false;
int sum = 0;
//switch condition check
if (p1 == 0)
{
escape_condition = true;
}
//if switch condition escape recursive call with return
if (escape_condition == true)
{
printf("Escape Recursive Call\n");
return 0;
}
//if not switch condition call. fold a logic
else {
//아래 코드에서 계속 해서 Stack에 함수가 쌓이면서
//호출 된다.
sum = p1 + rr_sum(p1 - 1);
}
//탈출 조건이 되면 드디어 return이 되고
//이전의 호출한 스택에 쌓여있던 함수들도
//return을 하면 코드가 완료 된다.
return sum;
}
재귀 함수의 기본적인 패턴에서 숫자를 더하는 로직이 더해지는
코드만 추가 되었다.
재귀함수 작성시 가장 중요한점
재귀호출은 특정 조건이 만족할때 까지 계속해서 함수호출을
통해 메모리(스택)를 사용하므로,탈출 조건이 정확히 만족하는지
해당 부분을 체크하는것이 가장 중요하다.
원하는 동작이 제대로 안되는것은 수정하면 되지만,
탈출 조건을 만족하지 못하는 재귀함수는 시스템을 다운 시킬수
있다.
따라서 재귀함수를 작성할때는 가장 먼저, 탈출 코드의 동작을
먼저 확인하고 상세 로직 코딩을 진행해야 한다.