標頭檔
頭文件(英語:Header file),或包含文件,是個在程序設計時,特別是在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
語句有兩種方式包含頭文件,分別是使用雙引號" "
與左右尖括號< >
。其區別是(對於不是使用完全文件路徑名的)頭文件的搜索順序不同:
使用雙引號" "
的頭文件的搜索順序:
- 包含該
#include
語句的源文件所在目錄; - 包含該
#include
語句的已經打開的頭文件的逆序(因為頭文件可以#include
另一個頭文件構成一個序列); - 編譯選項-I所指定的目錄
- 環境變量INCLUDE所定義的目錄
使用左右尖括號< >
的頭文件的搜索順序:
- 編譯選項-I所指定的目錄
- 環境變量INCLUDE所定義的目錄