The preprocessor handles directives beginning with # before compilation. It can define symbols, keep code conditionally, and include header contents. This is a textual preparation stage, so it does not understand variable types.
Macros
A macro replaces a name with text. Macros used as constants conventionally use uppercase names.
#include <stdio.h>
#define PI 3.1415926
double circle_area(double radius) {
return PI * radius * radius;
}
int main(void) {
double radius = 3.0;
printf("area = %.2f\n", circle_area(radius));
return 0;
}Function-like macros
A function-like macro resembles a function call, but creates no stack frame and performs no type checking. Arguments may be full expressions, so parenthesize every parameter use and the complete result. Avoid side-effecting arguments such as i++ when a macro repeats its parameter.
#include <stdio.h>
#define SQUARE(x) ((x) * (x))
int main(void) {
int n = SQUARE(3 + 1);
printf("n = %d\n", n);
return 0;
}KNOWLEDGE QUIZ
Macro expansion conveyor
Replace both occurrences of the SQUARE parameter, then follow the parentheses during evaluation. The preprocessor replaces text; it does not calculate values.
SQUARE is the macro name. The entire text 3 + 1 is the argument; no arithmetic happens yet.
Conditional compilation
#if selects source code when its condition is true, #else provides the alternative, and #endif closes the conditional group. These directives run before compilation, unlike a runtime if/else.
This circle-area calculator has two build modes: a debug build shows the radius and calculation result, while a release build shows only the area the user needs. Change DEBUG and recompile to switch the output.
#include <stdio.h>
#define PI 3.1415926
#define DEBUG 1
int main(void) {
double radius = 3.0;
double area = PI * radius * radius;
#if DEBUG
printf("[DEBUG] radius = %.2f, area = %.2f\n", radius, area);
#else
printf("Area: %.2f\n", area);
#endif
return 0;
}With DEBUG set to 1, the preprocessor keeps the #if branch and the output is [DEBUG] radius = 3.00, area = 28.27. Set it to 0 and recompile to keep only the #else branch, producing Area: 28.27. The unselected branch is not compiled.
#ifdef and #ifndef check whether a macro is defined; the next section uses #ifndef to protect a header.
KNOWLEDGE QUIZ
A circle calculator with switchable debugging
Build a circle calculator with switchable debug output.
- Define PI, SQUARE(x), and DEBUG.
- Read a radius and calculate the area and squared diameter.
- Print the original radius only when DEBUG is 1.
- Change DEBUG to 0 and confirm the debug line disappears.