一、编译预处理概念
1、编译预处理不是 C 语言本身的内容,是 C 编译系统提供的功能。在通常的编译之前,编译系统要预先对这些命令进行处理,之后才对 C 程序进行编译,生成目标代码。
特别注意:所有预处理命令均以 # 开头,末尾不加分号。
2、以下是三种预处理命令:
宏定义
#define PI 3.1415926
文件包含
#include <stdio.h>
#include "c_file1.c"
条件编译
#ifdef 标识符
// TODO1
#else
// TODO2
#endif
二、宏定义 & 文件包含 & 条件编译
1、宏定义
宏定义可以分为两种:1、不带参数的宏定义;2、带参数的宏定义。二者都是简单的字符串替换。
① 不带参数的宏定义
// 不带参数的宏定义方式
#define 标识符 一串字符
// 例如(以下宏定义中 PI 即为“宏名”):
#define PI 3.1415926
// 宏定义的作用:用 “标识符” 后的 “一串字符” 来替换程序中的 “标识符”
// 例如:#define PI 3.1415926
// 表示用 3.1415926 替换程序中的所有标识符 PI
// 参考代码
#include <stdio.h>
#define PI 3.1415926
int main(int argc, const char * argv[]) {
// r 表示半径;l 表示周长; s 表示面积
double r = 6, l = 0, s = 0;
l = 2 * PI * r; // 计算周长
s = PI * r * r; // 计算面积
printf("周长 = %.2f; 面积 = %.2f\n", l, s);
// 特别提醒:双引号中的 PI 不会被替换为 3.1415926
printf("PI = %.7f\n", PI);
return 0;
}
// 以上代码运行结果如下:
周长 = 37.70; 面积 = 113.10
PI = 3.1415926
*** 在预处理时,先做如下替换,然后才开始编译:***
l = 2 * PI * r; 会被替换成 l = 2 * 3.1415926 * r;
s = PI * r * r; 会被替换成 s = 3.1415926 * r * r;
*** 特别提醒:***
1> 宏名前后应有空格
2> 宏定义是用宏名代替一个字符序列,只是一种简单的替换,不进行正确性检查。
例如:
#define PI = 3.14abc15926
s = PI * r * r;
// 以上代码在预编译时只做替换操作,不会出错。在编译时才会报错。因为 3.14abc15926 不是合法的数字。
*** 易错提醒:***
#define PI 2 + 1.1415926
s = PI * r * r;
// s = PI * r * r; 展开后形式是:s = 2 + 1.1415926 * r * r; 由于运算符优先级问题此时计算的结果 s 是错误的。
// 应该将宏定义改为:
#define PI (2 + 1.1415926)
// 此时,s = PI * r * r; 展开后形式是:s = (2 + 1.1415926) * r * r; 计算结果正确