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 选项定义。