preprocessor directives (#include, #define, #ifdef)
A directive is a single line of instruction to the preprocessor. You can spot them instantly: they each start with a # symbol, usually at the very left edge of the line. They are not C statements, do not end with a semicolon, and are gone by the time the compiler runs. Think of them as sticky notes you leave for the text-pasting assistant who works before the compiler arrives.
The three you meet first are #include, #define, and the #ifdef family. The line #include <stdio.h> says 'paste in the contents of the stdio.h header here'. Angle brackets mean look in the system's standard places; double quotes, as in #include "myheader.h", mean look next to my own file first. The line #define NAME value says 'from here on, replace the word NAME with value'. The pair #ifdef NAME ... #endif says 'only keep the text in between if NAME has been defined; otherwise delete it', and #ifndef means 'only keep it if NAME is NOT defined'. There are more (#if, #else, #elif, #undef, #pragma) but these are the workhorses.
Directives are how you assemble a program out of many files and adapt it to different situations without changing your real code. Conditional ones let one source file compile differently on Windows versus Linux, or include debug printouts only when a DEBUG flag is set. The catch is that, because directives operate on raw text, an unbalanced #ifdef or a missing #endif produces errors that can be hard to trace, since the compiler sees only the wrongly-kept or wrongly-deleted text that results.
#include <stdio.h> /* paste the header in */ #define MAX 100 /* MAX becomes 100 everywhere below */ #ifdef DEBUG /* only compiled when DEBUG is defined */ printf("max is %d\n", MAX); #endif
Three directives doing three jobs: pasting, substituting, and conditionally keeping text.
Directives are not statements: there is no semicolon and they ignore C scope, so #define NAME inside a function still affects the whole rest of the file, not just that function.