6. 编译预处理
预处理发生在正式编译之前。命令都以 # 开头,不是 C 语句,末尾也不加分号。
6.1 文件包含
头文件里通常放类型定义、宏、常量和函数声明。为了防止同一个头文件被反复展开,要加包含保护:
#include 做的是原样插入文件内容。工程里包含头文件 .h,不要为了省事去 #include "file.c",否则源文件中的定义很容易重复。
6.2 条件编译
#ifdef DEBUG
fprintf(stderr, "x = %d\n", x);
#endif
#if VERSION >= 2
/* 新版本代码 */
#else
/* 兼容代码 */
#endif
defined(NAME) 可以在 #if 中检查宏有没有定义。条件编译是在编译前决定某段代码留不留下;普通 if 则是在程序运行时选择,两者不要混在一起。
6.3 #pragma 与 #line
#pragma 用来给编译器传一些额外指令,各家编译器不完全一样。课上重点是 #pragma pack(n):它会改结构体成员的对齐方式,用完要恢复,不然后面定义的结构体也会受影响。
#line 行号 "文件名" 修改编译器此后报告的逻辑行号和文件名,常用于代码生成工具,普通程序很少直接使用。