由于预处理命令不是 C 语言本身的组成部分,所以 C 编译程序不能识别它们,也就不能直接对它们进行编译,所以在 C 程序编译之前,必须先对预处理命令进行处理,处理后程序中不再包括预处理命令了,再由编译程序处理得到目标代码。C 语言提供的预处理命令共有三中:宏定义,文件包含和条件编译,预处理命令以 # 开头。
一、宏定义
# define
标识符 字符串
# define
宏名(参数表) 字符串
标识符也叫宏名,在编译时将宏名替换成字符串的过程,叫做宏展开。
宏名一般大写,与变量区别,但并非规定,可以用小写。
宏定义就是用宏名代替一个字符串,做简单置换,不做正确性检查,只有在编译已经宏展开后的源程序时才会去发现错误。
可以用 #undef 命令终止宏定义的作用域。
宏定义过程不分配内存空间,宏不存在类型问题。 宏替换不占运行时间,只占编译时间。注:其实这里书上说是编译时间,总感觉不是很合理,既然宏替换是在编译前替换的,替换完后才进行编译,所以并不是编译时间,合理来说应该是编译等待时间。
二、文件包含
一个源文件将另一个源文件包含进来,成为本文件的一部分。
命令是 # include “” 或 # include <>,引号和尖括号的区别是,后者是标准方式,系统到存放 C 库函数的目录寻找要包含的文件。前者先在用户当前目录寻找,找不到再按标准方式去找。一般的,包含库函数时用尖括号,包含自定义函数时,用双引号,也可以带路径,以便节省时间。
包含其实就是个复制插入的过程,该过程是发生在编译之前的。先将头文件包含到主文件,得到新的源程序,再对其进行编译,得到目标 .obj 文件。被包含文件作为包含文件的一部分,而单独生成目标文件。一定注意并不是对两个文件分别编译!!!
头文件常用 .h 做后缀,其实就是个习惯而已,用 .c 或者不用后缀也是可以的。
修改头文件后,包含头文件的文件都需要重新编译才行。
三、条件编译
程序编译时,是对源程序中的所有行进行编译,如果想在满足一定条件时对部分行编译,否则不编译,就可以节省编译时间,这时就可以用条件编译。
另外,条件编译可以减少编译后目标程序的长度,从而减少运行时间,提高运行效率,尤其在代码量大或程序复杂时优越性更为明显。
第一种形式:
# ifdef 标识符
// 程序段一
# else
// 程序段二
# endif
第二种形式:
# ifndef 标识符
// 程序段一
# else
// 程序段二
# endif
第三种形式:
# if 表达式
// 程序段一
# else
// 程序段二
# endif
注意:以上三种形式中,else 部分可以没有。