header files versus source files
A C project is split into two kinds of files that play very different roles. A source file (ending in .c) holds the actual code: the bodies of functions, the storage for variables, the real work. A header file (ending in .h) holds declarations: short promises of what exists, like the function's name, its parameter types, and what it returns, but not how it does the job. The header is the menu; the source file is the kitchen.
The split exists because of how separate compilation and translation units work. Each .c file is compiled on its own, in isolation, knowing nothing about the others. So when main.c wants to call a function add that lives in utils.c, main.c cannot see utils.c's code. Instead, you put a declaration of add (a function prototype, int add(int, int);) in a header utils.h, and main.c writes #include "utils.h". Now the compiler, processing main.c alone, has a promise that add exists with that shape, enough to generate a correct call. The actual code in utils.c is matched up later by the linker.
The guiding rule is: headers carry declarations (interface), source files carry definitions (implementation). A header should generally hold function prototypes, type definitions, and extern declarations, all wrapped in an include guard so it can be pasted in many times safely. It should not contain function bodies or plain variable definitions, because a header gets included into many translation units, and a definition pasted into many of them produces a 'multiple definition' linker error. Keeping the split clean lets one header be the single shared contract that many source files agree on.
/* utils.h -- the interface (declarations only) */ #ifndef UTILS_H #define UTILS_H int add(int a, int b); /* a promise: add exists */ #endif /* utils.c -- the implementation (the real definition) */ #include "utils.h" int add(int a, int b) { return a + b; }
The header declares add for everyone to share; exactly one source file defines it.
Never put a function body or a plain global definition in a header included by several files; pasting the same definition into many translation units causes a 'multiple definition' link error.