Preprocessor Directives & Macros

⚙️ C Language 🟢 Lesson 18 of 20 📅 2026 Edition
Lines in your C code starting with # are handled by the preprocessor — a separate step that runs before actual compilation begins, transforming your source code based on simple text-substitution rules.
1#include: Bringing in Libraries
C Language ▶ Run Code
#include <stdio.h>    // angle brackets: search system library folders
#include "myfile.h"    // quotes: search your own project folder first

This directive literally copies the entire contents of the named file directly into your source code at that exact point, before the compiler ever sees it — which is why header files typically only contain declarations, not full implementations.

2#define: Creating Macros
C Language ▶ Run Code
#define MAX_SCORE 100
#define PI 3.14159

int main() {
    printf("%d\n", MAX_SCORE);   // preprocessor replaces this with: printf("%d\n", 100);
    return 0;
}

The preprocessor performs a simple find-and-replace: every occurrence of MAX_SCORE in your code is swapped for 100 before compilation, with zero runtime cost at all.

3Function-Like Macros
C Language ▶ Run Code
#define SQUARE(x) ((x) * (x))

int main() {
    printf("%d\n", SQUARE(5));   // expands to ((5) * (5)) = 25
    return 0;
}

Always wrap macro parameters in parentheses like this — without them, SQUARE(2 + 3) would expand incorrectly into 2 + 3 * 2 + 3 (11) instead of the intended (2 + 3) * (2 + 3) (25), a classic macro pitfall.

4Conditional Compilation
C Language ▶ Run Code
#define DEBUG 1

int main() {
#if DEBUG
    printf("Debug mode is on\n");
#endif
    printf("Program running normally\n");
    return 0;
}

#if/#endif let you include or exclude entire blocks of code depending on a condition, decided at compile time rather than while the program runs — useful for toggling debug logging or supporting multiple platforms from one codebase.

⚠️ Common Mistake: Forgetting Parentheses in Function-Like Macros

As shown above, a macro like #define SQUARE(x) x * x (missing the parentheses) silently produces wrong results whenever it's called with an expression instead of a single value, because the preprocessor performs pure text substitution with no understanding of order of operations. Always wrap both the parameter and the entire macro body in parentheses.

💻 Try It Yourself

Define a macro that calculates the cube of a number (correctly parenthesized) and use it in a small program.

C Language ▶ Run Code
#include <stdio.h>

#define CUBE(x) ((x) * (x) * (x))

int main() {
    printf("%d\n", CUBE(3));   // 27
    printf("%d\n", CUBE(2 + 1)); // still 27, thanks to correct parentheses
    return 0;
}
Run This in Our Compiler →