頭文件是擴展名為?.h?的文件磕昼,包含了 C 函數(shù)聲明和宏定義卷雕,被多個源文件中引用共享。有兩種類型的頭文件:程序員編寫的頭文件和編譯器自帶的頭文件票从。
在程序中要使用頭文件漫雕,需要使用 C 預(yù)處理指令?#include?來引用它。前面我們已經(jīng)看過?stdio.h?頭文件峰鄙,它是編譯器自帶的頭文件浸间。
引用頭文件相當(dāng)于復(fù)制頭文件的內(nèi)容,但是我們不會直接在源文件中復(fù)制頭文件的內(nèi)容吟榴,因為這么做很容易出錯魁蒜,特別在程序是由多個源文件組成的時候。
A simple practice in C 或 C++ 程序中,建議把所有的常量兜看、宏锥咸、系統(tǒng)全局變量和函數(shù)原型寫在頭文件中,在需要的時候隨時引用這些頭文件细移。
引用頭文件的語法
使用預(yù)處理指令?#include?可以引用用戶和系統(tǒng)頭文件搏予。它的形式有以下兩種:
#include <file>
這種形式用于引用系統(tǒng)頭文件。它在系統(tǒng)目錄的標準列表中搜索名為 file 的文件弧轧。在編譯源代碼時雪侥,可以通過 -I 選項把目錄前置在該列表前。
#include "file"
這種形式用于引用用戶頭文件精绎。它在包含當(dāng)前文件的目錄中搜索名為 file 的文件速缨。在編譯源代碼時,可以通過 -I 選項把目錄前置在該列表前捺典。
引用頭文件的操作
#include?指令會指示 C 預(yù)處理器瀏覽指定的文件作為輸入鸟廓。預(yù)處理器的輸出包含了已經(jīng)生成的輸出,被引用文件生成的輸出以及?#include?指令之后的文本輸出襟己。例如,如果有一個頭文件 header.h牍陌,如下:
char *test (void);
和一個使用了頭文件的主程序?program.c擎浴,如下:
編譯器會看到如下的代碼信息:
只引用一次頭文件
如果一個頭文件被引用兩次,編譯器會處理兩次頭文件的內(nèi)容毒涧,這將產(chǎn)生錯誤贮预。為了防止這種情況,標準的做法是把文件的整個內(nèi)容放在條件編譯語句中契讲,如下:
#ifndef HEADER_FILE
#define HEADER_FILE
the entire header file file
#endif
這種結(jié)構(gòu)就是通常所說的包裝器?#ifndef仿吞。當(dāng)再次引用頭文件時,條件為假捡偏,因為 HEADER_FILE 已定義唤冈。此時,預(yù)處理器會跳過文件的整個內(nèi)容银伟,編譯器會忽略它你虹。
有條件引用
有時需要從多個不同的頭文件中選擇一個引用到程序中。例如彤避,需要指定在不同的操作系統(tǒng)上使用的配置參數(shù)傅物。可以通過一系列條件來實現(xiàn)這點琉预,如下:
但是如果頭文件比較多的時候董饰,這么做是很不妥當(dāng)?shù)模A(yù)處理器使用宏來定義頭文件的名稱。這就是所謂的有條件引用卒暂。它不是用頭文件的名稱作為?#include?的直接參數(shù)贮缅,只需要使用宏名稱代替即可:
#define SYSTEM_H "system_1.h"
?...?
#include SYSTEM_H
SYSTEM_H 會擴展,預(yù)處理器會查找 system_1.h介却,就像?#include?最初編寫的那樣谴供。SYSTEM_H 可通過 -D 選項被Makefile 定義。