头文档

进程设计中,特别是在C语言C++中,头文档包含文档是一个文档,通常是源代码的形式,由编译器在处理另一个源文档的时候自动包含进来。一般来说,进程员通过编译器指令将头文档包含进其他源文档的开始(或头部)。

一个头文档一般包含子进程变量和其他标识符前置声明。需要在一个以上源文档中被声明的标识符可以被放在一个头文档中,并在需要的地方包含这个头文档。

C语言C++中,标准库函数习惯上在头文档中声明,参见C标准函数库C++标准函数库

作用

在大多数现代计算机编程语言中,进程可以被分成如子进程的更小的组件,这些组件可以通过许多物理源文档分发,这些源文档被单独编译。当一个子进程在定义的位置以外的地方被使用时,就需要引入前置声明函数原型的概念。例如,一个函数在一个源文档中有如下定义:

 int add(int a, int b)
 {
     return a + b;
 }

在另一个源文档中引用的时候就可以声明成这样(包含函数原型):

 int add(int, int);
 
 int triple(int x)
 {
     return add(x, add(x, x));
 }

但是,这个简单的方法需要进程员为add在两个地方维护函数声明,一个是包含函数实现的文档,以及使用该函数的文档。如果函数的定义改变了,进程员必须要更改散布在进程中的所有的原型。

头文档提供了解决办法。模块的头文档声明作为模块公共接口一部分的每一个函数、对象以及数据类型。例如,在下面的情况下,头文档仅包含add的声明。每一个引用了add的源文档使用#include来包含头文档:

 /* File add.h */
 #ifndef ADD_H
 #define ADD_H
 
 int add(int, int);
 
 #endif /* ADD_H */
 /* File triple.c */
 #include "add.h"
 
 int triple(int x)
 {
     return add(x, add(x, x));
 }

这样就减少了维护的负担:当定义改变的时候,只须更新声明的一个独立副本(在头文档中的那个)。在包含对应的定义的源文档中也可以包含头文档,这给了编译器一个检查声明和定义一致性的机会。

 /* File add.c */
 #include "add.h"
 
 int add(int a, int b)
 {
     return a + b;
 }

通常,头文档被用来唯一指定接口,且多少提供一些文档来说明如何使用在该文档中声明的组件。在这个例子中,子进程的实现放在一个单独的源文档中,这个源文档被单独编译。(在C和C++中有个例外,即内联函数。内联函数通常放在头文档中,因为大多数实现如果不知道其定义,在编译时便无法适当的展开内联函数。)

替代

在访问声明在不同文档中的标识符问题上,头文档不是唯一的解决方法。他们也有缺点,当定义改变的时候可能仍然需要在两个地方来修改(头文档和源文档)。一些更新的语言(如Java)省略掉了头文档,而使用命名方案(naming scheme),这就允许编译器来定位与接口和类实现相关的源文档。

#include语句的两种语法

#include语句有两种方式包含头文档,分别是使用双引号" "与左右尖括号< >。其区别是(对于不是使用完全文档路径名的)头文档的搜索顺序不同:

使用双引号" "的头文档的搜索顺序:

  1. 包含该#include语句的源文档所在目录;
  2. 包含该#include语句的已经打开的头文档的逆序(因为头文档可以#include另一个头文档构成一个串行);
  3. 编译选项-I所指定的目录
  4. 环境变量INCLUDE所定义的目录

使用左右尖括号< >的头文档的搜索顺序:

  1. 编译选项-I所指定的目录
  2. 环境变量INCLUDE所定义的目录

参见

外部链接

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.