함수를 재귀적으로 호출하기
반복과 재귀는 복잡한 작업을 하나씩 작게 나누어 처리하고 그 결과를 조합한다는 면에서는 동일하다.
◾ 반복
필요한 처리를 계속 반복하면서 유지하는 것을 강조. 파일 스트림을 끝까지 읽을 때처럼 한계치까지 특정 처리를 실행할 때 주로 사용된다.
◾ 재귀
작업을 해결할 수 있을 때까지 작은 조각으로 나누는 것을 강조. 팩토리얼 등을 계산할 때 주로 사용된다.
반복으로 함수 호출
int factorial(int n)
{
int result = 1;
for (int i = 1; i <= n; ++i) result *= i;
return result;
}
for (int i = 1; i < 10; ++i)
std::cout << i << "! = " << factorial(i) << '\n';
재귀로 함수 호출
int factorial(int n)
{
if (n == 0)
return 1;
else
return n * factorial(n - 1);
}
for (int i = 1; i < 10; ++i)
std::cout << i << "! = " << factorial(i) << '\n';
재귀 호출이 많아지면 콜스택이 쌓여서 결국 스택 영역이 부족해지는 문제가 발생하게 되는데, 이 문제는 뒤에서 나올 꼬리 재귀에서 다룬다.
물론 위의 코드같은 경우는 콜스택이 쌓이기 전에 오버플로우로 인해 프로그램이 미정의 동작을 하게 될 수 있다.
불변 함수 반복 호출
재귀 함수는 상태를 변경할 필요가 없기 때문에 함수형 프로그래밍과 매우 잘 어울린다.
int fibonacci(int n)
{
if (n == 0) return 0;
int previous = 0;
int current = 1;
for (int i = 1; i < n; ++i) { // 값의 변경이 일어났기 때문에 순수 함수가 아니다
int next = previous + current;
previous = current;
current = next;
}
return current;
}
반복문을 사용하는 함수의 경우 값이 변하기 때문에 불변 객체가 아니다.
int fibonacci(int n)
{
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
재귀를 사용하면 코드가 간결해질 뿐만 아니라 자연스럽게 불변 객체가 된다.
마찬가지로 아직까지는 콜스택이 쌓이는 문제가 있다.
'도서 > 모던 C++로 배우는 함수형 프로그래밍' 카테고리의 다른 글
지연 평가로 실행 늦추기 (1) (0) | 2022.12.10 |
---|---|
재귀 함수 호출 (2) (0) | 2022.12.09 |
함수에 불변 객체 사용하기 (0) | 2022.12.09 |
함수형 프로그래밍에서 함수 다루기 (3) (0) | 2022.12.09 |
함수형 프로그래밍에서 함수 다루기 (2) (0) | 2022.12.09 |