C 头文件

预计时间: 4分钟

头文件是扩展名为**.h**的文件,其中包含要在多个源文件之间共享的 C 函数声明和宏定义。头文件有两种类型:程序员编写的文件和编译器附带的文件。

使用C预处理指令#include包含头文件,包含头文件相当于复制头文件的内容。

将所有常量、宏、系统范围的全局变量和函数原型保存在头文件中,并在需要的地方包含该头文件。

包含头文件语法

使用预处理指令#include包含用户和系统头文件。它有以下两种形式 -

#include <file>

这种形式用于系统头文件。它在系统目录的标准列表中搜索名为“file”的文件。您可以在编译源代码时使用 -I 选项将目录添加到此列表中。

#include "file"

这种形式用于你自己程序的头文件。它在包含当前文件的目录中搜索名为“file”的文件。您可以在编译源代码时使用 -I 选项将目录添加到此列表中。

理解包含操作

#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 ());
}

仅包含一次

如果一个头文件碰巧被包含了两次,编译器将处理它的内容两次,这将导致错误。 防止这种情况的标准方法是将文件的全部真实内容包含在条件中,如下所示 -

#ifndef HEADER_FILE
#define HEADER_FILE

// 内容部分...

#endif

此构造通常称为包装器 #ifndef。 当再次包含标头时,条件将为 false,因为定义了 HEADER_FILE。 预处理器会跳过文件的全部内容,编译器不会看到它两次。

计算的包含

有时有必要从几个不同的头文件中选择一个包含到您的程序中。 例如,他们可能会指定要在不同类型的操作系统上使用的配置参数。 您可以使用以下一系列条件来做到这一点 -

#if SYSTEM_1
   # include "system_1.h"
#elif SYSTEM_2
   # include "system_2.h"
#elif SYSTEM_3
   ...
#endif

但随着它的增长,它变得乏味,相反,预处理器提供了使用宏作为标头名称的能力。 这称为计算的包含(computed include)。无需将标头名称作为 #include 的直接参数,您只需在其中放置一个宏名称 -

#define SYSTEM_H "system_1.h"
...
#include SYSTEM_H

SYSTEM_H 将被扩展,预处理器将查找 system_1.h,就好像#include最初是这样编写的。

SYSTEM_H 可以由您的 Makefile 使用 -D 选项定义。

更新于2022年04月13日