Multi-File Programs
Header files, the compile-then-link model, and keeping code organized.
Real C programs are rarely one file. Splitting code across multiple .c files keeps related logic together and lets each file be compiled independently — only the files that changed need to be recompiled, which matters once a project grows large.
Header files declare, source files define
A header (.h) lists what a module offers, without the implementation. A source file (.c) provides the actual code:
math_utils.h
1#ifndef MATH_UTILS_H2#define MATH_UTILS_H34int square(int n);5int cube(int n);67#endif
math_utils.c
1#include "math_utils.h"23int square(int n) {4return n * n;5}67int cube(int n) {8return n * n * n;9}
main.c
1#include <stdio.h>2#include "math_utils.h"34int main(void) {5printf("%d\n", square(4));6printf("%d\n", cube(3));7return 0;8}
Compiling multiple files
terminal
1gcc main.c math_utils.c -o program2./program
Each .c file is compiled separately into an object file, then the linker (0x00) combines them into one executable. main.c only needs the header to know square and cube exist — it doesn't need to see how they're implemented.
note: Why the split matters as projects grow
With larger projects, you compile each changed file into an object file (
gcc -c file.c) and link the object files together, so an edit to one file doesn't require recompiling everything. Build tools like make automate exactly this.What goes in a header
- Function prototypes (declarations, not definitions).
structandtypedefdefinitions shared across files.#defineconstants meant to be shared.
error: Don't put function bodies in headers
If a header with a full function definition is included by two different
.c files, the linker sees that function defined twice and refuses to build — a "multiple definition" error. Headers declare; exactly one source file defines.