原创文章,转载请注明出处,谢谢!
作者:清林,博客名:飞空静渡
#include
如果从纯粹的text文件来说,#include的作用就是搜索它后面指示的文件,并把这个文件的内容加到当前的文件中。一般我们编程时,都是包含一些与.h为后缀的头文件,但是它可以包含任何后缀的任何形式的text文件的,而不仅仅是.h为后缀的头文件。
#include有两种形式,例如如下:
#include <syshead.h>
#include "userhead.h"
用尖括号表示的是包含系统的头文件,用双引号包含的是用户自己的头文件。
下面是使用#include时的一些规则:
1)使用<>包含的头文件一般会先搜索-I选项后的路径(即用gcc编译时的-I选项),之后就是标准的系统头文件路径。
3)在unix系统中,一般标准的头文件路径为:
8)#include后面所包含的文件名就是文件名,例如abc*d.h这个文件,必须就要有abc*d.h这个文件,而不是abckkkd.h这些文件,*不能解释成任
何的字符的意思,而是实实在在的一个字符。
9)可以使用一个指定的名字作为#include指令后面的头文件,例如:
#define BOGHEADER "bog_3.h"
#include BOGHEADER
10)在#include 指令的后面,除了所包含的头文件和注释外,不能包含其它的任何东西了。
#include_next
#include_next是GNU的一个扩展,并不是标准C中的指令。
#include_next看起来有些复杂,但在这里我将详详细细的说明一下,希望可以把它讲的清楚,让读者了解 :)
首先,我将会说明一下这条指令的功能,然后说明一下为什么要引人这条指令,希望能说个明白。
#include_next和#include指令一样,也是包含一个头文件,它们的不同地方是包含的路径不一样。
#include_next的意思就是“包含指定的这个文件所在的路径的后面路径的那个文件”,听起来是不是很坳口,我自己也觉得是这样,但下面举个例子说明就清楚了。
还有一点是#include_next是不区分<>和""的包含形式的。
现在来说说为什么要引人这条指令!
又进一步说,如果你这个新的头文件引用了旧的头文件,而这个新的头文件如果没有使用只编译一次的预处理语句包含(即#ifndef,#endif等),那么就会陷入一个无限的递归包含中,这个新的头文件就会无限的包含自己,就会出现一个致命的错误。如果我们使用#include_next就会避免这样的问题。
在标准的C中,这没有一个办法来解决上面的问题的,因此GNU就引人了这个指令#include_next。
下面再举一个#include_next的例子。
假设你用-I选项指定了一个编译包含的路径 '-I /usr/local/include',这个路径下面有个signal.h的头文件,在系统的'/usr/include'下也有个signal.h头文件,我们知道-I选项的路径首先搜索。如果我们这样 #include <signal.h> 包含,就会包含进/usr/local/include下的signal.h头文件;如果是 #include_next <signal.h>,就会包含 '/usr/include'下的signal.h头文件。
GNU建议一般没有其它可取代的办法的情况下才使用#include_next的。
又一个例子,如在系统头文件stdio.h中,里面有个函数(应该说是一个宏)getc,它从标准输入中读取一个字符。你想重新定义一个getc,并放到自己新建的stdio.h文件中,那么你可以这样使用你自定义的getc。
#include_next "stdio.h"
#undef getc
#define getc(fp) ((int)'x')
更多的说明请参考GNU的官方文档和GCC文档。