Recursion & Inline Functions
0%
C Functions  ·  Complete Lesson

Recursion & Inline
Functions in C

Two powerful function techniques — recursion that calls itself, and inline that removes the call entirely. Explained step by step with the sum() example.

What is recursion
Base case & recursive case
sum() step by step
Call stack trace
What is inline
When to use inline
§1

What is Recursion?

Core concept

Recursion means a function that calls itself. Instead of solving the whole problem at once, it breaks it down into a smaller version of the same problem — then calls itself on that smaller version.

Think of it like looking up a word in a dictionary. The definition uses another word you don't know. So you look that one up too. And that definition uses another word… until finally you reach a word you already know. That "word you already know" is the base case — the stopping point.

Every recursive function has exactly two parts:

  • Base case — the stopping condition. When this is true, the function returns a simple value and stops calling itself.
  • Recursive case — calls itself with a smaller input, getting closer to the base case each time.
Without a base case: the function calls itself forever, uses up all memory, and crashes. This is called a stack overflow. The base case is not optional.
the sum example
§2

The sum() Function — Adding 1 to 10

Main example

The problem: add all numbers from 1 to m. So sum(5) = 1+2+3+4+5 = 15.

The recursive insight: sum(5) = 5 + sum(4). You don't need to know the answer to sum(4) right now — just ask for it! The function handles the rest.

Recursive thinking — the pattern
sum(5) = 5 + sum(4)
sum(4) = 4 + sum(3)
sum(3) = 3 + sum(2)
sum(2) = 2 + sum(1)
sum(1) = 1 + sum(0)
sum(0) = 0              ← BASE CASE — stop here
sum_recursion.c
C
#include <stdio.h>

/* Prototype — tell compiler sum() exists before main uses it */
int sum(int m);

int main() {
    int result = sum(10);       /* add 1+2+3+...+10 */
    printf("Sum 1 to 10 = %d\n", result);  /* 55 */
    printf("Sum 1 to 5  = %d\n", sum(5));   /* 15 */
    printf("Sum 1 to 3  = %d\n", sum(3));   /* 6  */
    return 0;
}

int sum(int m) {
    if (m > 0) {
        return m + sum(m - 1);   /* recursive case: call with smaller m */
    } else {
        return 0;                 /* base case: m is 0, stop here */
    }
}
output
Sum 1 to 10 = 55
Sum 1 to 5  = 15
Sum 1 to 3  = 6
step by step trace
§3

Step by Step — How sum(5) Actually Runs

Call stack

When you call sum(5), the function doesn't immediately know the answer. It asks sum(4), which asks sum(3)... all the way down to sum(0). Then the answers travel back up, adding one number at a time.

There are two phases: going DOWN (building up calls) and coming back UP (collecting answers).

Phase 1 — going down (each call waits for the next)
call 1
sum(5)
5 + sum(4) = ?   waiting...
call 2
sum(4)
4 + sum(3) = ?   waiting...
call 3
sum(3)
3 + sum(2) = ?   waiting...
call 4
sum(2)
2 + sum(1) = ?   waiting...
call 5
sum(1)
1 + sum(0) = ?   waiting...
BASE
sum(0)
returns 0  ← STOPS here. No more calls.
Phase 2 — coming back up (answers travel back, adding each number)
unwind
sum(1)
1 + 0 = 1   returns 1
unwind
sum(2)
2 + 1 = 3   returns 3
unwind
sum(3)
3 + 3 = 6   returns 6
unwind
sum(4)
4 + 6 = 10  returns 10
unwind
sum(5)
5 + 10 = 15  ← final answer returned to main()
The full expansion on one line:
sum(5) = 5 + 4 + 3 + 2 + 1 + 0 = 15
sum(10) = 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 = 55
Live trace — try it yourself
5
answer
15
function calls
6
going down →
coming back up ↑
more recursion examples
§4

Two More Simple Recursive Programs

Practice

The same pattern works for many problems. Factorial and power are two classic examples that follow the exact same structure as sum().

factorial_recursive.c
C
#include <stdio.h>

/* factorial: 5! = 5 × 4 × 3 × 2 × 1 = 120 */
int factorial(int n) {
    if (n <= 1)
        return 1;             /* base case — 1! = 1 and 0! = 1 */
    return n * factorial(n - 1);  /* recursive case */
}

/* power: 2^8 = 2 × 2^7 = 2 × 2 × 2^6 ... */
int power(int base, int exp) {
    if (exp == 0)
        return 1;             /* base case — anything ^ 0 = 1 */
    return base * power(base, exp - 1);  /* recursive case */
}

int main() {
    printf("5!     = %d\n",  factorial(5));   /* 120  */
    printf("2^8    = %d\n",  power(2, 8));   /* 256  */
    printf("10^3   = %d\n",  power(10, 3));  /* 1000 */
    return 0;
}
output
5!     = 120
2^8    = 256
10^3   = 1000
FunctionBase caseRecursive case
sum(m)m == 0 → return 0return m + sum(m-1)
factorial(n)n <= 1 → return 1return n * factorial(n-1)
power(b, e)e == 0 → return 1return b * power(b, e-1)
The pattern is always the same: check if you've reached the simplest case (base case) → if yes, return a simple value. If not, do a small piece of work and call yourself with a slightly smaller input.
inline functions
§5

What is an Inline Function?

Speed trick

Every time you call a function, the CPU has to do extra work — jump to where the function lives in memory, set up a stack frame, do the work, then jump back. This is called function call overhead. For a big function it's worth it. For a tiny function that adds two numbers, the overhead can be as much work as the function itself.

An inline function solves this. You add the keyword inline before the function. The compiler sees this as a hint: "instead of making a jump to this function, just paste its code directly at the call site."

Syntax — adding inline keyword
inline return_type  function_name(parameters) {
    body;
}

/* Example */
inline int add(int a, int b) {
    return a + b;
}
What the compiler does with inline
int x = add(3, 5);
you write
int x = 3 + 5;
compiler generates
The function call disappears entirely. The arithmetic happens directly — no jump, no stack frame.
regular vs inline
§6

Regular Function vs Inline Function

Comparison
Regular function
compiler makes a jump to it
regular.c
int add(int a, int b) {
    return a + b;
}

int main() {
    int x = add(3, 5);
}
  • CPU jumps to add() in memory
  • sets up a stack frame
  • does the work
  • jumps back to main()
  • function exists once — saves memory
FeatureRegularInline
Call overheadYes — jump to functionNo — code pasted directly
SpeedSlightly slowerFaster for tiny functions
Binary sizeSmaller — one copyLarger if called many times
Best forAny size functionTiny 1–3 line functions
Compiler obeys?AlwaysIt's a hint — compiler decides
inline + recursion together
§7

Can sum() be Inline? Inline + Recursion

Key insight

You can write inline in front of sum(). It compiles fine. But here's the thing — the compiler will ignore the inline hint for recursive functions.

Why? Because inline means "paste the code at the call site". But sum(m) calls itself — to paste it, you'd need to paste infinite copies of the code inside each other. That's impossible. So the compiler quietly treats it as a regular function.

inline_sum.c
C
#include <stdio.h>

/* inline keyword is here — but compiler ignores it for recursion */
inline int sum(int m) {
    if (m > 0) {
        return m + sum(m - 1);   /* calls itself — can't be inlined */
    } else {
        return 0;
    }
}

/* THIS can actually be inlined — no recursion, tiny, fast */
inline int square(int n) {
    return n * n;               /* one line — perfect for inline */
}

inline int isEven(int n) {
    return n % 2 == 0;        /* one line — perfect for inline */
}

int main() {
    printf("sum(10)    = %d\n", sum(10));       /* 55  */
    printf("square(7)  = %d\n", square(7));     /* 49  */
    printf("isEven(8)  = %d\n", isEven(8));     /* 1   */
    printf("isEven(9)  = %d\n", isEven(9));     /* 0   */
    return 0;
}
output
sum(10)    = 55
square(7)  = 49
isEven(8)  = 1
isEven(9)  = 0
inline is a hint, not a command. The compiler makes the final decision. If it thinks inlining would be harmful (function too large, recursive, or called too many places), it ignores your hint and compiles it as a regular function. Your program still works — it's just not inlined.
Best candidates for inline: square(n), max(a,b), min(a,b), isEven(n), abs(n) — tiny one-liners called inside loops thousands of times. For everything else, regular functions are fine.
quiz
Q

Quick Quiz

Question 1 of 4

What happens if a recursive function has NO base case?

Question 2 of 4

What does sum(4) return based on the sum() function in this lesson?

Question 3 of 4

What does the inline keyword tell the compiler to do?

Question 4 of 4

Why does adding inline to the recursive sum() function have no effect?

Lesson Checklist

  • A recursive function is one that calls itself
  • Every recursive function must have a base case — the stopping condition
  • sum(m) = m + sum(m-1) — recursive case; sum(0) = 0 — base case
  • Recursion has two phases: going down (building calls) and coming back up (collecting answers)
  • Without a base case: infinite recursion → stack overflow crash
  • inline tells the compiler to paste function code at the call site — no jump needed
  • inline is a hint — the compiler can ignore it
  • inline is best for tiny 1–3 line functions like max(), square(), isEven()
  • inline on recursive functions is ignored — recursion cannot be inlined
  • I completed the quiz