1. 预处理指令#include
预处理指令#include
对于我们来说已经不陌生了。从第一个输出"Hello
World"的代码开始,预处理指令#include
几乎出现在每一个代码当中。现在我们将进一步探究,为什么需要#include
指令?#include
指令有哪些使用方式?
就拿最开始的输出"Hello World"的代码来举例,并假设该源代码文件名为main.c
。
源文件main.c
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
当编译器从上到下编译源文件main.c
时,需要先知道标识符printf
是一个函数。接着,在后面的代码中,我们才能将标识符printf
当做函数来使用。而我们最常用的让编译器识别printf
的方式就是使用预编译指令#include <stdio.h>
。
预处理指令#include
,会将文件stdio.h
中的代码复制到该预处理指令出现处,并删除该预处理指令。
我们暂时假设文件stdio.h
含有函数printf
的定义。
文件stdio.h
// printf函数的定义
int printf (const char *__format, ...)
{
...
XXXXXXXX
...
}
经过预处理后,源文件main.c
的源码将变为:
int printf (const char *__format, ...)
{
...
XXXXXXXX
...
}
int main()
{
printf("Hello World\n");
return 0;
}
修改后的代码将另存为中间文件或直接输入到编译器。并不会保存到源文件中。所以,请放心,预处理器不会改动你的源文件。
经过预处理后,编译器使用修改后的代码进行编译。编译器首先会读取到函数printf
的定义。因此,在其后的main
函数中调用printf
函数可以通过编译。但是,这样做还存在其他问题,我们将会继续讨论。
2. #include的两种形式
预处理指令#include
有两种形式:
#include <文件名>
#include "文件名"
- 文件名在尖括号内: 将会在编译器的包含目录中搜索文件。
- 文件名在双引号内: 先在当前目录中搜索文件,再到编译器的包含目录中搜索文件。
对于stdio.h
文件来说,它是编译器自带的文件,在编译器的包含目录中。所以使用尖括号,即可找到该文件。
双引号的使用我们稍后再举例。