Recursion is a powerful concept in computer science where a function calls itself directly or indirectly. In this chapter, we will explore the fundamentals of recursion in the C programming language, starting from its basic concepts to more advanced techniques.
Recursion is a programming technique where a function calls itself to solve a problem. It breaks down a complex problem into smaller, more manageable subproblems, making it easier to solve.
#include
void countDown(int n) {
if (n == 0)
return;
printf("%d\n", n);
countDown(n - 1); // Recursive call
}
int main() {
countDown(5);
return 0;
}
// output //
5
4
3
2
1
countDown()
takes an integer n
as input.n
and calls itself with n-1
, until n
becomes 0.n
down to 1.A base case is a condition where the function stops calling itself and returns a value. It prevents infinite recursion.
void factorial(int n) {
if (n == 0)
return 1; // Base case
else
return n * factorial(n - 1); // Recursive call
}
The recursive case is where the function calls itself with a modified input to solve a smaller subproblem.
void fibonacci(int n) {
if (n <= 1)
return n; // Base case
else
return fibonacci(n - 1) + fibonacci(n - 2); // Recursive call
}
Tail recursion is a special case of recursion where the recursive call is the last operation performed by the function. Tail recursion optimization is a compiler optimization technique that optimizes such recursive functions to avoid stack overflow by reusing the same stack frame for each recursive call.
Let’s first understand what tail recursion is. In a recursive function, a tail recursive call occurs when the recursive call is the last thing executed by the function before it returns. This means there’s no pending computation after the recursive call.
Consider this example of a tail-recursive function to calculate the factorial of a number:
#include
int factorial(int n, int result) {
if (n == 0)
return result;
else
return factorial(n - 1, n * result);
}
int main() {
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num, 1));
return 0;
}
In this code:
factorial
function takes two arguments: n
, the number for which factorial is to be calculated, and result
, the current result of the computation.n
becomes 0.factorial(n - 1, n * result)
is the last operation performed by the function.Tail recursion optimization offers several benefits:
Let’s illustrate tail recursion optimization with the factorial function we discussed earlier.
#include
int factorial(int n, int result) {
if (n == 0)
return result;
else
return factorial(n - 1, n * result);
}
int main() {
int num = 5;
printf("Factorial of %d is %d\n", num, factorial(num, 1));
return 0;
}
// output //
Factorial of 5 is 120
factorial(5, 1)
is called from main
.factorial
, n
is decremented at each recursive call, and result
is updated with the product of n
and the current result
.n
becomes 0, the base case is reached, and the final result is returned.Recursion is a powerful programming technique where a function calls itself to solve smaller instances of a problem. It simplifies complex problems by breaking them into base and recursive cases. Key points to remember include defining a clear base case to prevent infinite loops and ensuring the problem size reduces with each recursive call. While recursion is elegant and intuitive for tasks like tree traversal or factorial computation, it may require careful consideration of stack usage and efficiency.Happy coding !❤️