Code before the compiler: the preprocessor
Use headers, symbolic macros, include guards, and conditional compilation without hiding program logic.
After this lesson
You should be able to
- Explain how preprocessing changes a translation unit before compilation.
- Use object-like macros and include guards safely.
Text transformation with a narrow job
Preprocessor directives begin with # and run before normal C compilation. #include brings declarations from a header into the translation unit. Angle brackets search implementation header paths; quotes normally search the project location first.
#define performs token substitution; it does not create a typed variable. Prefer const objects or enum constants when type and scope matter. Use macros for genuine preprocessing needs, and parenthesize every parameter and the full result of a function-like macro.
#ifndef SCORE_H
#define SCORE_H
int clamp_score(int score);
#endifCompile one of several versions
#if evaluates a preprocessing constant expression. #ifdef checks whether a name is defined; #ifndef checks whether it is absent. These directives can select platform-specific code or debugging diagnostics before compilation.
#undef removes a macro definition from that point onward. Conditional compilation should remain small and explicit; scattering feature branches through business logic makes every version difficult to reason about.
#ifdef DEBUG
fprintf(stderr, "score=%d\n", score);
#endifTry it yourself
Write an include guard for a header named lesson.h.
Need a hint?
Use a project-specific uppercase name and pair #ifndef with #define and #endif.
Check the worked solution
A guard prevents the header body from being processed more than once in one translation unit.
#ifndef CHADUVU_BIDDA_LESSON_H
#define CHADUVU_BIDDA_LESSON_H
/* declarations */
#endifQuick check
Which directive tests that a macro name has not been defined?
Why this lesson exists
Syllabus mapping
include · define · undef · if · ifdef · ifndef directives
Maps to course outcomes CO2, CO3, CO4.