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 定義。