Step 1 of 7
Headers and include guards
Real C programs are thousands or millions of lines, split across many files. Understanding how those files fit together is essential for working on any real codebase.
Modules: a header and a source file
Each module usually has two files:
- A header (
score.h) with declarations: type definitions, function prototypes and constants. It's the module's public interface: what other code may use. - A source file (
score.c) with the definitions: the actual function bodies. It#includes its own header.
Other files #include "score.h" (quotes for your own headers, angle brackets for system headers) and can then call its functions.
How it's built
The compiler turns each .c file into an object file separately, knowing only what its includes declared. Then the linker joins all the object files, connecting each call to the matching definition. If a definition is missing, the linker reports an error like undefined reference to 'kd_ratio' (or undefined symbol: kd_ratio); if something is defined twice, multiple definition (or duplicate symbol).
Include guards
#include pastes a file's text. Headers often end up included more than once (main.c includes a.h and b.h, and both include score.h), and defining the same struct twice is an error. An include guard makes repeat inclusions disappear:
#include <stdio.h>
#ifndef GREETING_H
#define GREETING_H
#define GREETING "hi"
typedef struct { int times; } Repeat;
#endif
#ifndef GREETING_H
#define GREETING_H
#define GREETING "hi"
typedef struct { int times; } Repeat;
#endif
int main(void) {
Repeat r = {2};
for (int i = 0; i < r.times; i++) printf("%s\n", GREETING);
return 0;
}
hi
hi
The first time, GREETING_H isn't defined, so everything up to #endif is kept, and GREETING_H gets defined. The second time, #ifndef GREETING_H is false and the preprocessor skips the whole block. Many compilers also accept #pragma once at the top of a header for the same effect.
The editor here holds a single file, so this program pastes the "header" in twice to simulate a double include. Your turn: complete the guard so it compiles.