← Core SyntaxC PROGRAMMING 1.1.E

Functions

Definitions, prototypes, void params/returns, parameters as local copies, multiple returns, local vs global, static locals, recursion basics.

StatusCollected
NotesChapter test: 4/4

Nine pieces, and the one that actually matters most for everything after this chapter is that parameters are copies. That single fact is the entire reason pointers exist.

Definition, prototypes, and void

int add(int a, int b);      /* prototype — tells the compiler this exists before it's defined */

int add(int a, int b) {     /* definition */
    return a + b;
}

void log_message(void);     /* no params */
void print_status(int s);   /* no return value */

A prototype has to exist before the first call site, or the compiler has no way to check the call is even valid — either a full definition earlier in the file, or a one-line prototype up top.

Parameters are local copies

void increment(int x) {
    x = x + 1;      /* only changes the local copy */
}

int main(void) {
    int a = 5;
    increment(a);   /* a is still 5 after this */
    return 0;
}

C is pass-by-value, always. A function gets its own copy of every argument, and changes to that copy never propagate back to the caller. Wanting a function to actually modify a caller's variable is what makes pointers necessary, not optional — pass &a and take an int *x parameter instead.

Return values, local vs global, and static

  • A function can only return one value directly — multiple "returns" in practice means output parameters (pointers) or a struct.
  • Local variables live and die with the function call; globals live for the whole program and are visible everywhere unless static-restricted to one file.
  • A static local is the odd one out — declared inside a function, but keeps its value between calls instead of resetting, because it's actually allocated once in static storage, not on the stack.

Recursion

int factorial(int n) {
    if (n <= 1) return 1;         /* base case — without this, infinite recursion */
    return n * factorial(n - 1);  /* recursive case */
}

Every recursive function needs a base case that stops the recursion, and every recursive call needs to move measurably closer to it. Skip either one and it recurses until it blows the stack.

Notes from readers

Comments — via GitHub