第十四章、编译预处理
你还记得一个写好的 C 语言程序文件最终编译成可执行程序需要几步吗?
当一个编写好的 .c 文件通过编译器变为二进制可执行文件一共经过四个阶段。
这四个阶段分别是:
- 预处理(Preprocessing)。
- 编译(Compilation)。
- 汇编(Assembly)。
- 连接(Linking)。
这一章我们先学习 C 语言的编译的第一步,编译预处理的指令。
C 语言的预处理指令都是以英文的井号(#)开头,在编译器进行正式编译之前执行。
预处理指令有如下几种:
- 文件包含指令:
#include - 宏定义指令:
#define。 - 取消宏定义指令:
#undef。 - 条件编译指令,
#if、#endif等。 - 停止编译报错指令
#error。 - 编译参数设定
#pragma。
这一章我们先学习前五种预处理指令。
1. 文件包含
文件包含指令 是以 #include 开头的指令,它的作用主要是在预处理阶段将其它文件的内容插入到当前文件。
使用 文件包含 的好处是当多个文件都需要使用一段共有代码的时候,每个文件都抄写一份这段代码,这增大了工作量,同时也不方便程序的修改。在这种情况下我们可以将这段共有代码放入到一个文件中,然后使用文件包含指令 #include 插入到需要使用这段代码的文件中即可。
在 C 语言中。一般函数的声明或者变量的声明等共有代码通常放入一个 .h 为后缀的文件中。我们把这个以 .h 结尾的文件称为头文件。因为这部分代码通常放在一个文件的最上端。
文件包含的语法有两种
// 方法1
#include <文件路径>
// 方法2
#include "文件路径"
说明:
#include <文件路径>优先查找系统文件的路径,如果没有才查找本地路径。#include "文件路径"优先查找本地的路径,如果没有才查找系统文件路径。文件路径一般使用相对路径。
示例:
以下我们使用多个文件来实现打印一行 hello world!。
文件 print.c 内容如下:
printf("hello world!\n");
文件 main.c 内容如下:
#include <stdio.h>
int main(int argc, char *argv[]) {
#include "print.c"
return 0;
}
使用 GCC 编译 main.c 运行结果如下:
weimingze@mzstudio:~$ gcc -o hello main.c
weimingze@mzstudio:~$ ./hello
hello world!
可见, #include "print.c" 将 print.c 中的内容 printf("hello world!\n"); 插入到了 main 函数中。
实验:
完成上述示例代码的编写。然后使用自己的编译器查看预处理后的 main.c 文件的内容。如在 GCC 编译器下可以使用如下命令查看预处理后的结果。
gcc -E main.c