The Preprocessor
#include, #define, and macros — text substitution before compilation.
Before your code is compiled, it passes through the preprocessor — a text-substitution step that handles every line starting with #. It doesn't understand C; it just rewrites your source file according to a small set of directives, and hands the result to the compiler.
#include
You've used this since chapter 0x00. It literally pastes the contents of another file in place:
1#include <stdio.h> // a standard library header, in angle brackets2#include "helpers.h" // a header file of your own, in quotes
Angle brackets tell the compiler to look in the system's standard include paths; quotes look in your project first.
#define: constants and macros
1#define MAX_USERS 1002#define PI 3.1415934int users[MAX_USERS];5float area = PI * radius * radius;
Every occurrence of MAX_USERS is replaced with 100 before compilation even begins — the compiler never sees the name MAX_USERS at all. const variables (0x01) are usually preferred for simple constants today, since they have a real type the compiler can check.
Function-like macros
1#define SQUARE(x) ((x) * (x))23int result = SQUARE(5); // expands to ((5) * (5))
1#define SQUARE(x) x * x23SQUARE(2 + 3); // expands to 2 + 3 * 2 + 3 → 11, not 25
Conditional compilation
#ifdef and related directives include or exclude code before compilation, commonly used for platform-specific code or debug-only logging:
1#define DEBUG23#ifdef DEBUG4printf("Debug: entering main\n");5#endif
Include guards
Header files use a guard to prevent being pasted into the same file twice — essential once a project has multiple files including the same header, covered next in 0x0F:
1#ifndef HELPERS_H2#define HELPERS_H34// declarations go here56#endif