Lesson 14 — Advanced
Preprocessor & Macros
Compiler chalne se ek second pehle ek chhota program chalta hai jo sirf text badalta hai — preprocessor. #include yahin expand hota hai, #define ke macros yahin replace hote hain. Is lesson mein hum directives, function-like macros (unke traps ke saath) aur conditional compilation dekhenge.
Preprocessor kya hai
WHAT
Preprocessor compilation ka PEHLA step hai — wo C code nahi, TEXT badalta hai. # se shuru wali har line directive hai: #include, #define, #ifdef. Semicolon nahi lagta directives mein.
WHEN
Header files jodni hon (#include), constant/function define karni ho (#define), ya platform ke hisaab se code chunna ho (#ifdef) — preprocessor yahin kaam aata hai.
WHERE
Har C file ke top pe. stdio.h ka poora content tumhare file mein paste hona — preprocessor ka hi kaam hai. Include guards bhi isi se hain.
#include <stdio.h> // poora header FILE khol kar paste kar do
#define PI 3.14159 // aage PI likha = 3.14159 likha
int main() {
printf("%f\n", PI); // → printf("%f\n", 3.14159);
return 0;
}
Output: 3.141590
- Ye TEXT replacement hai: koi function call nahi, koi runtime cost nahi — compiler ko milta hai pehle hi badla hua code.
- # se shuru: har directive. Semicolon nahi chahiye (#define PI 3.14; likhoge toh ";" bhi replace hoga — galti!).
- Stages: preprocessor → compiler → assembler → linker. Ye step pehla hai (lesson 1 mein dekha tha).
Macro types — object-like aur function-like
#include <stdio.h>
#define SQUARE(x) ((x) * (x)) // function-like (sahi)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define BAD(x) x * x // GALAT (brackets nahi)
int main() {
printf("%d\n", SQUARE(5)); // 25
printf("%d\n", SQUARE(2 + 3)); // 25 ((2+3)*(2+3)) — sahi!
printf("%d\n", MAX(10, 20)); // 20
printf("%d\n", 10 / SQUARE(2)); // 2 (10 / (2*2)) — sahi
printf("%d\n", 10 / BAD(2)); // 5 — 10/2*2 = 5 GALAT!
return 0;
}
Output:
25
25
20
2
5 ← BAD macro ka jaadu
- Object-like: #define PI 3.14 — bas value replace.
- Function-like: #define SQ(x) ((x)*(x)) — function jaisa dikhta hai par andha text hai (type check nahi).
- Double evaluation: SQUARE(i++) mein i DO baar badhega — macro mein side-effect wale argument se bacho.
- Type-safe alternative: C99 inline function — check bhi, call overhead bhi nahi.
Conditional compilation — #ifdef ka khel
#define DEBUG 1
#ifdef DEBUG
printf("Debug mode ON: line %d\n", __LINE__);
#endif
#ifndef HEADER_H // include guard
#define HEADER_H
// ... header ka content ...
#endif
// Real use — platform specific:
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
Ye tab chalta hai jab preprocessor shart poori ho: #ifdef (defined hai?), #ifndef (defined NAHI hai?), #else, #endif (band). File ke beech mein rukna mat bhoolo — #endif ke baad sab normal.
- Include guards: #ifndef FILE_H / #define FILE_H — ek hi header do baar include ho toh definition dup nahi hoga. Har header file mein standard hai.
- #pragma once: include guard ka modern (compiler wala) version — ek line ka.
- Debug code: #ifdef DEBUG se debugging prints ek jagah — release build mein hat jaate hain (program tez).
- Makhluk: #undef PI — macro khatam (defined nahi rahega).
Predefined macros aur directives ki poori list
#include <stdio.h>
int main() {
printf("File = %s\n", __FILE__); // main.c
printf("Line = %d\n", __LINE__); // 6 (isi line ka number)
printf("Date = %s\n", __DATE__); // Oct 18 2026
printf("Time = %s\n", __TIME__); // 10:30:00
// #error compiler ko rok deta hai:
// #error "Yahan compilation fail karo"
return 0;
}
Directive Kya karta hai
#include header paste
#define / #undef macro banao / mitao
#ifdef/#ifndef condition (defined?)
#else / #endif conditional ka else / end
#line line number badal do
#error compilation error message
#pragma compiler ko hint (once, pack)
Predefined: __FILE__ __LINE__ __DATE__ __TIME__ __STDC__
Macro vs function: macro fast hai (no call overhead, par code badh sakta hai), function safe hai (type check, debugging). Aaj kal small helpers ke liye inline function hi pasand kiya jaata hai — macro sirf constants aur conditionals ke liye rakho.
Exercise
Question: Har preprocessor directive kis character se shuru hoti hai? (# ya $)
Question: #include kis stage mein process hota hai — preprocessor ya linker?
Question: #define SQUARE(x) ((x)*(x)) — SQUARE(2+3) ka output? Sirf number daalo.
Question: Ek header do baar include hone se bachne wale guards ka naam? (do shabd — include guard)
Common mistakes
- Macro arguments ko bina bracket ke likhna: #define SQ(x) x*x → 10/SQ(2) = 5 (galat). Hamesha ((x)*(x)) — har argument bracket mein.
- Macro ko function samajhna: Macro mein type check nahi, side-effect ho sakta hai (i++ do baar). Function jaisa dikhta hai, hota nahi.
- #define ke baad semicolon laga dena: #define PI 3.14; — semicolon bhi replace ho jaata hai aur aage expressions toot-te hain. Directive pe semicolon nahi.
Rate board pe likha "Chai = 15" — ab jahan bhi board dikhe, 15 hi lagta hai. #define bhi yahi karta hai: ek jagah likho, jagah jagah replace:
#define CHAI_RATE 15
bill = CHAI_RATE * 3; // → 15 * 3 = 45
#ifdef SUNDAY
rate = CHAI_RATE / 2; // sirf Sunday code
#endif
Ek jagah badlo → poore program mein badal gaya- TCS NQT: macro expansion output (SQUARE jaise) — 1Q aksar.
- GATE: #define vs const, preprocessor stage, include guards.
- College exam: macro se max/area program likhwana + #ifdef use.
- Trap: "macro function hai" — galat, wo preprocessor ka text replacement hai.
Preprocessor clear. Ab last lesson — Top 50 C Questions — poore course ka interview power-pack.