当前位置:首页 > 学习资源 > 讲师博文 > C语言的include没你想的那么简单

C语言的include没你想的那么简单 时间:2024-01-16      来源:华清远见

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进来。

上一篇:如何编写分层清晰、通用性高的LCD驱动?

下一篇:使用HTML5的canvas标签进行图形绘制、动画和游戏开发的方法和技巧

戳我查看嵌入式每月就业风云榜

点我了解华清远见高校学霸学习秘籍

猜你关心企业是如何评价华清学员的

干货分享
相关新闻
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2024 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号-5京公海网安备11010802025203号

回到顶部