上篇手動在 main.c 宣告函數原型雖可行,但隨模組增長極不擴展。頭文件將共用宣告集中管理,#include 即等同於批量複製宣告碼,實現介面與實作分離。
/* game.h */ #ifndef GAME_H #define GAME_H #include#include #include extern int gen_rnd(void); extern void judge(int, int); #endif
extern 明確標示外部鏈接,函數預設即為 extern 可省略。#ifndef)防止重複定義錯誤。extern 且定義於所有函數外部。#include 對應頭文件。gcc main.c gen_rnd.o judge.o -o exe 或鏈接靜態庫。| 包含形式 | 搜尋順序 |
|---|---|
#include <syshdr.h> | -I 指定目錄 → 系統標準目錄(如 /usr/include) |
#include "userhdr.h" | 當前 .c 檔目錄 → -I 目錄 → 系統標準目錄 |
相對路徑亦可寫於包含指令:#include "subdir/my.h"。
將多個 .o 打包為 .a 靜態庫:
ar rs libgame.a gen_rnd.o judge.o
ar 專用於靜態庫建立,r 替換/新增,s 建立索引供鏈接器快速查找。lib 前綴 + 名稱 + .a 後綴。gcc main.c -L. -lgame -o main(-L 指定庫目錄,-l 鏈接 libgame.a)add())不會進入最終可執行檔,減小體積。#include "judge.c"?直接包含原始檔會導致重複編譯、符號多重定義、編譯時間暴增,且破壞模組邊界。正確做法:.h 宣告介面,.c 實作細節,鏈接期綁定。