C - 头文件


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

您请求在程序中使用头文件,方法是将其包含在 C 预处理指令#include中,就像您看到的包含stdio.h头文件一样,该文件随编译器一起提供。

包含头文件等于复制头文件的内容,但我们不这样做,因为它很容易出错,并且在源文件中复制头文件的内容不是一个好主意,特别是如果我们一个程序中有多个源文件。

C 或 C++ 程序中的一个简单做法是,我们将所有常量、宏、系统范围的全局变量和函数原型保留在头文件中,并在需要的地方包含该头文件。

包含语法

使用预处理指令#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 ());
}

编译器将看到与读取program.c时相同的令牌流。

int x;
char *test (void);

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

一次性标头

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

#ifndef HEADER_FILE
#define HEADER_FILE

the entire header file file

#endif

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

计算包含

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

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

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

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

SYSTEM_H 将被扩展,预处理器将查找 system_1.h,就好像#include最初是这样编写的。SYSTEM_H 可以由 Makefile 使用 -D 选项定义。