C预处理器-6(include的语法、操作、搜索路径)

2.1 Include语法

用户头文件和系统头文件都通过预处理指令 #include 来包含。它有两种形式:

#include <file>

这种形式用于系统头文件。它会在标准的系统目录列表中搜索名为 file 的文件。你可以使用 -I 选项(参见 调用选项)向该列表中添加目录。

#include "file"

这种形式用于你程序中的头文件。它首先在当前文件所在的目录中搜索名为 file 的文件,然后在引号目录(quote directories)中搜索,最后在与 <file> 相同的目录中搜索。你可以使用 -iquote 选项向引号目录列表中添加目录。

#include 的参数(无论是用引号还是尖括号括起来)的行为类似于字符串常量:注释不会被识别,宏名称也不会被展开。因此,#include <x/*y> 指定了一个名为 x/*y 的系统头文件。

然而,如果文件名中包含反斜杠(\),它们会被视为普通文本字符,而不是转义字符。C 语言字符串常量中适用的字符转义序列不会被处理。因此,#include "x\n\\y" 指定的是一个包含三个反斜杠的文件名。(某些系统将 \ 解释为路径分隔符,所有这些系统也将 / 解释为相同的方式。为了最大程度的可移植性,建议仅使用 /。)

如果在文件名之后的行上还有其他内容(注释除外),则会导致错误。

2.2 Include操作

#include 指令的作用是指示 C 预处理器在继续处理当前文件的其余部分之前,先扫描指定的文件作为输入。预处理器的输出包含以下内容:已经生成的输出,接着是被包含文件产生的输出,最后是 #include 指令之后文本生成的输出。例如,如果你有一个头文件 header.h,其内容如下:

char *test (void);

以及一个使用该头文件的主程序 program.c,内容如下:

int x;
#include "header.h"

int
main (void)
{
  puts (test ());
}

编译器看到的标记流将与以下代码等效:

 

int x;
char *test (void);

int
main (void)
{
  puts (test ());
}

被包含的文件不仅限于声明和宏定义;这只是它们的典型用途。C 程序的任何片段都可以从另一个文件中包含进来。被包含的文件甚至可以包含一条语句的开头部分,而这条语句在包含它的文件中结束;或者它可能包含一条语句的结尾部分,而这条语句在包含它的文件中开始。然而,被包含的文件必须由完整的标记组成。如果注释或字符串字面量在被包含文件的末尾未关闭,则是无效的。为了错误恢复,这些未关闭的内容会被视为在文件末尾结束。

为了避免混淆,最好确保头文件只包含完整的语法单元——函数声明或定义、类型声明等。

即使被包含文件缺少末尾的换行符,#include 指令后的下一行也始终被 C 预处理器视为单独的一行。

2.3 搜索路径

默认情况下,预处理器会首先在当前文件所在目录中查找由引号形式的指令 #include "file" 包含的头文件,然后在预配置的标准系统目录列表中查找。例如,如果 /usr/include/sys/stat.h 包含 #include "types.h",GCC 会首先在 /usr/include/sys 中查找 types.h,然后在其通常的搜索路径中查找。

对于尖括号形式的 #include <file>,预处理器的默认行为是仅在标准系统目录中查找。确切的搜索目录列表取决于目标系统、GCC 的配置方式以及安装位置。你可以通过使用 -v 选项调用 CPP 来查看你的版本的默认搜索目录列表。例如:

bash

cpp -v /dev/null -o /dev/null

你可以使用一些命令行选项来向搜索路径中添加额外的目录。最常用的选项是 -Idir,它会使 dir 在当前目录之后(对于引号形式的指令)和标准系统目录之前被搜索。你可以在命令行中指定多个 -I 选项,在这种情况下,目录会按照从左到右的顺序进行搜索。

如果你需要对引号形式和尖括号形式的 #include 指令的搜索路径进行单独控制,可以使用 -iquote 和/或 -isystem 选项,而不是 -I。有关这些选项以及其他较少使用的选项的详细说明,请参见 调用选项(Invocation)。

如果你在命令行上指定了其他影响预处理器搜索头文件路径的选项(如 -I),那么由 -v 选项打印的目录列表将反映预处理器实际使用的搜索路径。

请注意,你可以使用 -nostdinc 选项阻止预处理器搜索任何默认的系统头文件目录。这在编译操作系统内核或其他不使用标准 C 库功能的程序时非常有用,或者在编译标准 C 库本身时也可以使用该选项。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值