预处理器与宏
#include/#define/#ifdef、宏函数陷阱、条件编译
预处理器与宏
预处理是编译的第一步——在真正编译之前,先做文本替换。#define 不是变量定义,是纯粹的文本替换。
学完本章你将: 掌握 #include/#define/宏函数陷阱/#ifdef 条件编译。
#define 宏常量
c
#include <stdio.h>
#define PI 3.1415926
#define MAX(a, b) ((a) > (b) ? (a) : (b)) // 宏函数
int main() {
double area = PI * 10 * 10;
printf("面积:%.2f\n", area);
int m = MAX(3, 5);
printf("MAX(3,5) = %d\n", m); // 5
return 0;
}
宏函数的致命陷阱
c
#define SQUARE(x) x * x
// ❌ 展开后的意外
int result = SQUARE(2 + 3);
// 展开:2 + 3 * 2 + 3 = 2 + 6 + 3 = 11(不是 25!)
// ✅ 修复:参数加括号
#define SQUARE_SAFE(x) ((x) * (x))
// 💡 宏函数规则:每个参数加括号,整体也加括号
c
// ❌ 带副作用的宏
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int x = 5, y = 3;
int z = MAX(x++, y++);
// 展开:(x++ > y++ ? x++ : y++) — x 或 y 被加了两次!
⚠️ 现代 C 中,推荐用
static inline函数替代宏函数,类型安全且无副作用。
条件编译
c
#define DEBUG
#ifdef DEBUG
printf("调试:x = %d\n", x); // 定义了 DEBUG 就编译这句
#endif
#ifndef VERSION
#define VERSION "1.0" // 如果没定义则定义
#endif
#if defined(_WIN32)
printf("Windows\n");
#elif defined(__linux__)
printf("Linux\n");
#endif
预定义宏
c
printf("文件名:%s\n", __FILE__);
printf("行号:%d\n", __LINE__);
printf("日期:%s\n", __DATE__);
printf("时间:%s\n", __TIME__);