$ overview
overview/0x06·Functions & Data

Functions

Splitting programs into reusable pieces: declarations, scope, and recursion.

A function is a named, reusable block of code. Every C program already has at least one — main — and splitting logic into more of them is how you keep programs readable as they grow.

Defining and calling a function

square.c
1#include <stdio.h>
2 
3int square(int n) {
4 return n * n;
5}
6 
7int main(void) {
8 int result = square(6);
9 printf("%d\n", result); // 36
10 return 0;
11}

A function signature has three parts: a return type (int), a name (square), and a parameter list (int n). return both produces the function's result and immediately exits it.

Declarations vs. definitions

C reads top to bottom, so a function normally has to appear before it's used. When you need to call a function before its full definition — often because two functions call each other — declare it first with a prototype:

prototype.c
1int square(int n); // prototype: promises this function exists
2 
3int main(void) {
4 printf("%d\n", square(4)); // fine — the compiler trusts the prototype
5 return 0;
6}
7 
8int square(int n) { // full definition, can come later in the file
9 return n * n;
10}

void functions

A function that doesn't return a value uses void as its return type:

greet.c
1void greet(const char *name) {
2 printf("Hello, %s!\n", name);
3}

const here promises the function won't modify the string it's given — a useful signal to callers and to the compiler.

Parameters are passed by value

C copies each argument into the function's parameters. Changes made inside the function don't affect the caller's variable:

by-value.c
1void increment(int n) {
2 n = n + 1; // only changes the local copy
3}
4 
5int main(void) {
6 int x = 5;
7 increment(x);
8 printf("%d\n", x); // still 5
9 return 0;
10}
note: To modify a caller's variable, pass its address
Functions that need to change a caller's data take a pointer parameter instead. This is covered once pointers are introduced in 0x09 — it's the same mechanism scanf uses.

Recursion

A function can call itself. Every recursive function needs a base case that stops the recursion, or it will call itself forever (and eventually crash with a stack overflow):

factorial.c
1int factorial(int n) {
2 if (n <= 1) return 1; // base case
3 return n * factorial(n - 1); // recursive case
4}