C语言中的include很简单,我们认为就是用来包含头文件的,
#include命令是预处理命令的一种,预处理命令可以将别的源代码内容插入到所指定的位置;可以
标识出只有在特定条件下才会被编译的某一段程序代码;
可以定义类似标识符功能的宏,在编译时,预处理器会用别的文本取代该宏。但它真的是这么简单吗?
#include<stdio.h>
#include"drv_led.h"//
我们在写程序时对于它的用法就如上面写的一样,在需要用到某个函数时,就引用一下函数声明的头
文件,那上面两种写法有什么不一样呢:
使用尖括号<>和双引号""的区别在于头文件的搜索路径不同:
1、使用尖括号<>,编译器会到系统路径下查找头文件;
2、使用双引号"",编译器首先在当前目录下查找头文件,如果没有找到,再到系统路径下查找
有些人还将整个所有的.h文件全部包含在一个includes.h的头文件中,然后在其他.c文件里
面,就直接#include"includes.h"。这么写看视好像简单化了程序但是我们从上面的分析看,
#include就是将它后面包含的头文件源文件,全部展开。所以上这样写法带来的最直接的感
受就是编译过程慢!includes.h里包含得越多就越慢!另外一个隐含的问题是,会造成include
里的内容混乱,头文件里的内容全部是全局的了。不建议这么去操作。那么如果一个头文件,
有多个地方被使用,会不会被重复包含多次呢?重复包含头文件会导致编译报错,因为重复
include,就相当于把头文件重复展开了多次,C语言中有些定义是不允许重复多次的,那用
什么办法可以解决呢?可以用#ifdef...#endif这种方式规避。例如
#ifdef_DEBUG_
#defineMY_HEADER"myled.h"
#else
#defineMY_HEADER"mydelay.h"
#endif
#includeMY_HEADER
上面这种写法是当上述程序代码进入预处理时,如果DEBUG宏已被定义,那么预处理器会插入
myled.h的内容;如果还没定义,则插入mydelay.h的内容。
那么预处理器如何找到头文件
由给定的C语言实现版本决定#include命令所指定文件的搜索路径。同时,也由实现版本决定文
件名是否区分大小写。对于命令中使用尖括号指定的文件(),预处理器通常会在特定的系统路径下
搜索,例如,在Unix系统中,会搜索路径/usr/local/include与/usr/include。
对于命令中用双引号指定的文件("文件名"),预处理器通常首先在当前目录下寻找,也就是包含该
程序其他源文件的目录。如果在当前目录下没有找到,那么预处理器也会搜索系统的include路径。
文件名中可以包含路径。但如果文件名中包含了路径,则预处理器只会到该目录下寻找。
你也可以通过使用编译器命令行选项,或在环境变量(该变量通常称为INCLUDE)中加入搜索路径,
为#include命令指定自己的搜索路径。
但其实#include在C语言中,算是预编译指令(preprocessingdirective)范畴,在C99标
准中它是由一个源文件和一些由#include包含着的headers和sourcefiles,通过预编译后,变成
一个叫translationunit的东西。所以从这里可以看出来,#include不但可以包含headers,还可
以包含源文件,也就是说我们在程序里面也可以像下面这么写
#include"add.h"
#include"minus.c"
除了*.h和*.c文件,我还可以这么写
//main.c#include"multiply.txt"
intmain(void){inte=multiply(2,2);return0;}
甚至,这样也行
//main.c#include"devide.fxxk"
intmain(void){intf=devide(2,2);return0;}
我们一般是将#include放在文件上方,其实也可以放中间
//main.cintmain(void){#include"squel.xx"intg=squel(2,2);return0;}
那能不能将data.txt换成二进制形式的data.bin呢?这种就不行,因为编译器在预编译阶段
只认得是text文本。好吧……你不是说这是个预编译指令吗,我很好奇,#include预编译后
成啥样子的?这好办,动动手指头,一个gcc-E命令即可搞定。就以上面第一个例子,命令
行执行gcc./main.c-E-omain.i
#0".\main.c"#0""#0"<命令行>"#1".\main.c"
#1"add.h"1externintadd(inta,intb);#3".\main.c"2#1"minus.c"1intminus(inta,intb){return
a-b;}#4".\main.c"2
intadd(inta,intb){returna+b;}
intmain(void){intc=add(1,2);intd=minus(2-1);return0;}
看到了吧,#include就是把它后面的文件内容直接include进来。