許多 C 語言初學者對原始檔 (.c) 與標頭檔 (.h) 的關係存在模糊認知,甚至產生「編譯器會自動綁定同名 .c/.h」的錯誤想法。本文從編譯器視角重新釐清概念,並解答三個經典問題。
對編譯器而言,.c、.h、.txt、.doc 並無本質差異,皆為純文字檔。副檔名僅是慣例,預處理器處理 #include "xxx.h" 時,只是將該行替換為檔案內容而已。
extern 變數、結構/聯合/列舉定義、巨集、inline 函式static/inline 的函式本體、非 extern 的變數實體(否則多檔 #include 導致重複定義錯誤)Q1: a.c 中
#include "a.h"是否多餘?
A: 不一定。若 a.c 內部函式互相調用,若無#include "a.h"需自行排序宣告順序;引入標頭檔可統一管理宣告,許多專案將其列為編碼規範。Q2: 為何常見 xx.c 包含對應 xx.h?
A: 同 Q1,確保自身實作符合對外宣告的介面,且免去手動維護宣告順序。Q3: 不寫 include,編譯器會自動綁定同名 .h 嗎?
A: 絕不會。此想法極度錯誤,編譯器無此機制。提此問題者概念不清,切勿被誤導。
#pragma once 或傳統 #ifndef _XXX_H_ / #define _XXX_H_ / #endif理解 編譯單元、連結階段、One Definition Rule (ODR),可徹底消除對 .c/.h 關係的迷思。良好的模組化設計,始於清晰的標頭檔介面。