Lesson 24
Recursion
Recursion in C is a technique where a function calls itself to solve a problem by breaking it into smaller subproblems. Every recursive function requires a base case to stop execution and a recursive case that reduces the problem size. Recursive calls are managed using the call stack.
C Track
Save progress as you learn.
44 lessons
Lesson content
Recursion in C Programming: A Complete Beginner to Advanced Guide
What is Recursion in C Programming?
Recursion in C programming is a technique where a function calls itself to solve a problem. Instead of solving the entire problem at once, recursion breaks it into smaller, similar subproblems until a simple condition is reached.
Think of recursion like looking into two mirrors facing each other. Each reflection creates another reflection, but eventually the reflections become too small to notice. Similarly, a recursive function keeps calling itself until it reaches a stopping point called the base case.
Why Does Recursion Exist?
Some problems naturally have a repetitive structure. Writing loops for these problems can become complicated, while recursion often produces cleaner and easier-to-understand code. Recursion is commonly used in:
- Tree traversal
- Graph algorithms
- Divide-and-conquer algorithms
- Searching nested folders
- Mathematical computations
- Backtracking algorithms
- Compiler design
Prerequisites
Before learning Recursion in C, you should understand:
- Variables
- Data types
- Functions
- Function parameters
- Return values
- if-else statements
- Loops
- Basic understanding of the call stack (helpful but not mandatory)
Core Concepts of Recursion in C
What is a Recursive Function?
A recursive function is simply a function that calls itself. Every recursive function has two essential parts:
| Part | Purpose |
|---|---|
| Base Case | Stops recursion |
| Recursive Case | Calls the function again |
Without a base case, recursion never stops.
Syntax
return_type function_name(parameters)
{
// Base case
// Recursive call
}Base Case
The base case is the stopping condition. Without it, the function keeps calling itself forever.
if (n == 0)
return 1;Recursive Case
The recursive case reduces the problem into a smaller version. Each call gets closer to the base case.
return n * factorial(n - 1);The Call Stack
Every recursive function call is stored in memory on the call stack. Once the smallest problem finishes, each call returns in reverse order until the original call completes.
Code Examples
Example 1: Beginner – Print Numbers Using Recursion
#include <stdio.h> // Include standard input/output library
void printNumbers(int n) // Recursive function
{
if (n == 0) // Base case
return; // Stop recursion
printNumbers(n - 1); // Recursive call
printf("%d ", n); // Print current number
}
int main(void)
{
printNumbers(5); // Function call
return 0; // End program
}Output: 1 2 3 4 5
Example 2: Intermediate – Factorial Using Recursion
#include <stdio.h> // Standard input/output
int factorial(int n) // Recursive function
{
if (n == 0 || n == 1) // Base case
return 1; // Return factorial of 0 or 1
return n * factorial(n - 1); // Recursive case
}
int main(void)
{
int number = 5; // Store number
printf("%d\n", factorial(number)); // Print factorial
return 0; // End program
}Output: 120
Example 3: Intermediate – Fibonacci Series
#include <stdio.h> // Standard library
int fibonacci(int n) // Recursive function
{
if (n <= 1) // Base case
return n; // Return 0 or 1
return fibonacci(n - 1) + // First recursive call
fibonacci(n - 2); // Second recursive call
}
int main(void)
{
int i; // Loop variable
for (i = 0; i < 8; i++) // Print first 8 terms
{
printf("%d ", fibonacci(i)); // Print Fibonacci number
}
return 0; // End program
}Output: 0 1 1 2 3 5 8 13
Example 4: Advanced – Sum of Digits
#include <stdio.h> // Standard input/output
int sumDigits(int n) // Recursive function
{
if (n == 0) // Base case
return 0; // Stop recursion
return (n % 10) + // Last digit
sumDigits(n / 10); // Remaining digits
}
int main(void)
{
int number = 4567; // Store number
printf("%d\n", sumDigits(number)); // Print digit sum
return 0; // End program
}Output: 22
Example 5: Advanced – Binary Search Using Recursion
#include <stdio.h> // Standard input/output
int binarySearch(int arr[], int left, int right, int key) // Recursive function
{
if (left > right) // Base case
return -1; // Key not found
int mid = (left + right) / 2; // Middle index
if (arr[mid] == key) // Key found
return mid; // Return index
if (key < arr[mid]) // Search left half
return binarySearch(arr, left, mid - 1, key); // Recursive call
return binarySearch(arr, mid + 1, right, key); // Search right half
}
int main(void)
{
int arr[] = {2, 4, 6, 8, 10, 12, 14}; // Sorted array
int size = sizeof(arr) / sizeof(arr[0]); // Calculate array size
int index = binarySearch(arr, 0, size - 1, 10); // Search for value
printf("%d\n", index); // Print result
return 0; // End program
}Output: 4
Common Mistakes and Pitfalls
| Wrong | Correct |
|---|---|
| return factorial(n); | return factorial(n - 1); |
| Missing base case | Always define a stopping condition |
| Recursive call never changes input | Reduce the problem size with each call |
| Deep recursion causing stack overflow | Consider an iterative solution for very large inputs |
| Using recursion for simple loops | Use loops when they are simpler and more efficient |
Wrong:
int fun(int n)
{
return fun(n); // Infinite recursion
}Correct:
int fun(int n)
{
if (n == 0)
return 0;
return fun(n - 1);
}Best Practices
- Always write the base case first.
- Ensure every recursive call moves closer to the base case.
- Keep recursive functions focused on a single task.
- Use descriptive function names.
- Avoid unnecessary recursive calls.
- Prefer iteration when recursion adds complexity without improving readability.
- Be aware of stack memory usage for deeply recursive functions.
- Test edge cases such as 0, 1, negative numbers (if applicable), and empty inputs.
When NOT to Use Recursion
Avoid recursion when:
- The recursion depth can become very large, increasing the risk of a stack overflow.
- A simple loop solves the problem more efficiently.
- Performance is critical and repeated recursive calls introduce unnecessary overhead.
- The recursive solution recomputes the same values many times (for example, the naive recursive Fibonacci implementation). In such cases, use memoization or an iterative approach.
- Memory usage must be kept to a minimum.
Summary / Key Takeaways
- Recursion in C programming is a technique where a function calls itself.
- Every recursive function requires a base case to stop execution.
- The recursive case reduces the problem into a smaller version of itself.
- Recursive calls are managed using the call stack.
- Recursion often leads to cleaner solutions for problems involving trees, graphs, divide-and-conquer algorithms, and backtracking.
- Poorly designed recursion can cause infinite recursion or stack overflow.
- Loops are often a better choice for straightforward repetitive tasks.
- Practice with problems such as factorial, Fibonacci, sum of digits, binary search, and tree traversal to become comfortable with recursion.
FAQ About Recursion in C
1. What is recursion in C programming?
Recursion is a programming technique where a function solves a problem by calling itself until a base case is reached.
2. What is the difference between recursion and iteration?
Recursion uses function calls and the call stack, while iteration uses loops such as for and while. Iteration is generally more memory-efficient, whereas recursion can make certain algorithms easier to express.
3. Why is a base case important?
Without a base case, a recursive function never stops calling itself, eventually causing a stack overflow and terminating the program.
4. Is recursion slower than loops?
In many cases, yes. Recursive calls involve function-call overhead and additional stack usage. However, recursion can greatly simplify algorithms whose structure is naturally recursive.
5. Where is recursion used in real-world software?
Recursion is widely used in file system traversal, tree and graph algorithms, binary search, Quick Sort, Merge Sort, Depth-First Search (DFS), and backtracking problems such as maze solving, Sudoku solvers, and the N-Queens puzzle.