C 標頭檔案

C 標頭檔案

標頭檔案是副檔名為 .h 的檔案,包含了 C 函式宣告和巨集定義,被多個原始檔中引用共享。有兩種型別的標頭檔案:程式設計師編寫的標頭檔案和編譯器自帶的標頭檔案。

在程式中要使用標頭檔案,需要使用 C 預處理指令 #include 來引用它。前面我們已經看過 stdio.h 標頭檔案,它是編譯器自帶的標頭檔案。

引用標頭檔案相當於複製標頭檔案的內容,但是我們不會直接在原始檔中複製標頭檔案的內容,因為這麼做很容易出錯,特別在程式是由多個原始檔組成的時候。

A simple practice in 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 ());
}

編譯器會看到如下的程式碼資訊:

int x;
char *test (void);

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

只引用一次標頭檔案

如果一個頭檔案被引用兩次,編譯器會處理兩次標頭檔案的內容,這將產生錯誤。為了防止這種情況,標準的做法是把檔案的整個內容放在條件編譯語句中,如下:

#ifndef HEADER_FILE
#define HEADER_FILE

the entire header file file

#endif

這種結構就是通常所說的包裝器 #ifndef。當再次引用標頭檔案時,條件為假,因為 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 可通過 -D 選項被您的 Makefile 定義。