Introduction to Recursion
Recursion is a programming technique where a function calls itself to solve a problem by breaking it down into smaller, similar sub-problems. Each recursive call works on a simpler version of the original problem until reaching a base case that can be solved directly.Basic Recursion Example
Here’s a simple example that prints a string using recursion:- Base case: When we reach the null terminator (
'\0'), print a newline and return - Recursive case: Print the current character, then call the function with the next character
- Progress: Each call moves one character forward in the string
Mathematical Recursion
Factorial Calculation
Factorial is a classic example of recursion. The factorial of n (n!) is the product of all positive integers less than or equal to n.factorial(5):
Power Function
Calculating powers using recursion demonstrates how to handle multiple conditions:Advanced Recursion with Helper Functions
Square Root Calculation
Some recursive problems require a helper function to maintain additional state:- The main function has a clean interface (
_sqrt_recursion(n)) - The helper function manages the iteration variable (
sqroot) - This pattern is common when you need to track additional state
Prime Number Detection
Another example using a helper function to check divisibility:Recursion vs Iteration
Advantages
- Clean, elegant code for naturally recursive problems
- Easier to understand for tree/graph operations
- Matches mathematical definitions
Disadvantages
- Uses more memory (call stack)
- Can be slower than iteration
- Risk of stack overflow with deep recursion
Common Recursive Patterns
Linear Recursion
The function makes a single recursive call:Tail Recursion
The recursive call is the last operation in the function:Best Practices
-
Always define a clear base case
- Without it, your function will recurse infinitely
- Test edge cases (0, negative numbers, empty strings)
-
Ensure progress toward the base case
- Each recursive call should move closer to the base case
- Otherwise, you’ll have infinite recursion
-
Consider the call stack depth
- Deep recursion can cause stack overflow
- For large inputs, iteration might be better
-
Use helper functions when needed
- Keep the public API simple
- Use helpers to manage additional parameters
Practice Problems
The0x08-recursion directory includes implementations of:
_puts_recursion()- Print a string recursively_print_rev_recursion()- Print a string in reverse_strlen_recursion()- Calculate string lengthfactorial()- Calculate factorial_pow_recursion()- Calculate power_sqrt_recursion()- Find square rootis_prime_number()- Check if number is prime
Key Takeaways
- Recursion solves problems by breaking them into smaller instances
- Every recursive function needs a base case and recursive case
- Helper functions are useful for managing additional state
- Consider memory usage and stack depth for large inputs
- Some problems are naturally recursive (trees, graphs, mathematical sequences)
Related Topics
Function Pointers
Learn about passing functions as arguments
Variadic Functions
Master functions with variable arguments