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