# Functions and Recursion in C — Prototypes, Call by Value, Storage Classes

Source: https://skills101.in/learn/c-programming/c-functions-and-recursion — Skills101 free tutorial (C Programming). Updated 2026-11-09.

A **function** is a named block of code that does one job. C programs are built from many small functions.

## 1. Declare, define, call

```c
#include <stdio.h>

int square(int n);              /* prototype (declaration) */

int main(void) {
    printf("%d %d\n", square(4), square(square(2)));
    return 0;
}

int square(int n) {             /* definition */
    return n * n;
}
```

```text
16 16
```

- The **prototype** tells the compiler the function's name, return type and parameters before it's used.
- A function that returns nothing has return type `void`.

## 2. Call by value (C's only way)

![Calling swap(a, b) copies the values into x and y, so swapping the copies leaves a and b unchanged; calling swap(&a, &b) passes addresses, so the function changes the originals through pointers](https://skills101.in/learn-img/c-programming/call-value-ref.svg)

C **copies** each argument into the parameter. Changing the parameter doesn't change the caller's variable:

```c
#include <stdio.h>

void broken_swap(int x, int y) { int t = x; x = y; y = t; }
void swap(int *x, int *y) { int t = *x; *x = *y; *y = t; }

int main(void) {
    int a = 5, b = 9;
    broken_swap(a, b);
    printf("after broken_swap: %d %d\n", a, b);
    swap(&a, &b);
    printf("after swap:        %d %d\n", a, b);
    return 0;
}
```

```text
after broken_swap: 5 9
after swap:        9 5
```

To let a function change the caller's variable, pass its **address** (a pointer). This is often called "call by reference", but technically C copies the pointer — still pass-by-value.

## 3. Recursion

A **recursive** function calls itself. It needs:
1. a **base case** that stops, and
2. a **smaller step** towards it.

```c
#include <stdio.h>

long long factorial(int n) {
    if (n <= 1) return 1;            /* base case */
    return n * factorial(n - 1);     /* smaller step */
}

int fib(int n) {
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2);
}

int sum_digits(int n) {
    if (n == 0) return 0;
    return n % 10 + sum_digits(n / 10);
}

int main(void) {
    printf("%lld %d %d\n", factorial(10), fib(10), sum_digits(9875));
    return 0;
}
```

```text
3628800 55 29
```

Each call gets its own stack frame. Too deep recursion → **stack overflow** (crash). Plain recursive `fib` is slow (exponential) — fine for learning, use a loop for big n.

## 4. Storage classes

| Class | Where it lives | Lifetime | Default value | Example use |
|---|---|---|---|---|
| `auto` (default for locals) | stack | the function call | garbage | normal local variables |
| `static` (local) | data segment | **whole program** | 0 | counting calls |
| `extern` | data segment | whole program | 0 | a global defined in another file |
| `register` | CPU register (a hint) | the block | garbage | loop counters (compilers ignore it today) |

### static keeps its value between calls

```c
#include <stdio.h>

void visit(void) {
    static int count = 0;   /* initialised once */
    int normal = 0;         /* reset every call */
    count++; normal++;
    printf("count=%d normal=%d\n", count, normal);
}

int main(void) {
    visit(); visit(); visit();
    return 0;
}
```

```text
count=1 normal=1
count=2 normal=1
count=3 normal=1
```

## 5. Scope

- **Local** variables exist only inside their block `{ }`.
- **Global** variables (outside all functions) are visible everywhere in the file — use sparingly.
- An inner variable with the same name **hides** the outer one.

## Common mistakes

- Calling a function before declaring it (add a prototype).
- Recursion without a base case → infinite recursion → crash.
- Expecting a normal (non-pointer) parameter to change the caller's variable.

## Quick recap

- Prototype → definition → call; `void` for no return value.
- C copies arguments; pass addresses (pointers) to modify the caller's data.
- Recursion = base case + smaller step.
- `static` locals keep their value across calls and start at 0.


Practice quiz and free certificate: https://skills101.in/learn/c-programming/c-functions-and-recursion