何为预处理?
还记得之前说过的c语言的特点吗?
c语言是一个编译的语言
但是从我们写出来的源码,到生成可执行文件(程序),中间并不是仅仅通过了编译这个过程。
在编译之前,其实还有一个预处理阶段。
以下面这个程序为例
#include <stdio.h> #define str "hello!" int main(void) { printf(str); return 0; }
请复制这一段代码,完成编译、执行后再接着往下看
如果你成功了,他应该显示一行hello
在这个程序中,我们使用了两个预处理指令。
就是开头的include和define
像这样以前面以#开头的命令,都属于预处理命令
include前面已经讲过,它的作用是把外部的文件包含进来。相当于把stdio.h这个文件中的内容放到include这个命令的为位置
include有两种写法,一种是#include <…>,另一种是#include “…”。
两者的区别在于,用<>括起来的文件默认目录在编译器的include目录,这里一般是各种库文件,如stdio.h, stdlib.h, string.h等等等等
而第二种写法,用””包含起来的文件,预处理器会先在工程目录搜索(就是你程序源码保存的目录),如果没有找到,再到默认的include目录内查找。
也就是说,我们如果写了一个头文件,并且需要在程序中使用。那么我们可以把这个头文件放到include目录下,使用第一种方法包含它
或者放在工程目录,使用第二种方法包含它。
第一种方法不推荐使用,特别是那种为了某个工程专门写的头文件。毕竟你只需要在这个工程用一次。但是如果你在很多不同的工程中,都要使用这个头文件。使用第二种方法还需要把这个头文件往每个工程目录复制一次,这样又太麻烦了。这时就需要使用第一种方法了
下面再来看第二个预编译指令:define
define的英文意思就是定义,他在这里的意思也是定义。定义“宏”
它的作用就是替换。
在上面的程序里,我们定义了一个str宏,然后我们在printf中使用了它。
预处理器在处理你的源代码时,发现了str,就将他替换为了”hello!”
但是并不是所有的str都被替换,比如被双引号包括起来的字符串中的str就不会被替换。请自己尝试,在printf中的str前后加上”,别忘了是英文状态下加
还有,如果有一个函数叫做strs,这里的str也不会被替换,因为str和strs是两个不同的标识符。(就是说完全相同才会替换)
除了上面介绍的两个预处理命令
还有下面这些
- #undef指令删除一个宏定义
- #if,#ifdef,#ifndef,#elif,#else和#dendif指令可以根据编译器可以测试的条件来将一段文本包含到程序中或排除在程序之外。
- #pragma 修改编译器的设置
- #error 产生错误信息
关于这些命令的使用,我们将在后面进行学习