標頭檔

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書

程序設計中,特別是在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(naming scheme),這就允許編譯器來定位與接口和類實現相關的源文件。

#include語句的兩種語法[編輯]

#include語句有兩種方式包含頭文件,分別是使用雙引號" "與左右尖括號< >。其區別是(對於不是使用完全文件路徑名的)頭文件的搜索順序不同:

使用雙引號" "的頭文件的搜索順序:

  1. 包含該#include語句的源文件所在目錄;
  2. 包含該#include語句的已經打開的頭文件的逆序(因為頭文件可以#include另一個頭文件構成一個序列);
  3. 編譯選項-I所指定的目錄
  4. 環境變量INCLUDE所定義的目錄

使用左右尖括號< >的頭文件的搜索順序:

  1. 編譯選項-I所指定的目錄
  2. 環境變量INCLUDE所定義的目錄

參見[編輯]

外部連結[編輯]