C 語言

宣告與定義之別

假設朋友提到「一位叫 Sam 的同事」。現在你知道 Sam 存在、是個人,但你還沒見過 Sam,也還沒幫他安排辦公室。引入這個名字與種類就是宣告。真正空出一張桌子、把 Sam 帶進來才是定義。C 正好劃下這條界線:宣告告訴編譯器某個名字存在、是什麼型別;定義則是真正建立那個東西並保留儲存空間(對函式而言,是提供它的本體)。

對變數而言,在檔案範圍寫「int count;」是定義——它既命名 count 又配置儲存空間。寫「extern int count;」只是宣告——它承諾 count 定義在別處,也許在另一個原始檔。對函式而言,「int add(int a, int b);」是宣告(原型)——它宣布函式的形狀,好讓呼叫端能被檢查——而「int add(int a, int b) { return a + b; }」是給出實際程式碼的定義。原則是:每個名字可以被宣告很多次,但在整個程式中必須剛好被定義一次(單一定義規則)。

為什麼重要:這個劃分正是讓大型程式能橫跨許多檔案的關鍵。標頭檔攜帶宣告,好讓每個檔案對共用函式與變數的形狀有共識,而每個定義剛好放在某一個原始檔裡。弄錯了連結器就會抱怨:未定義參考表示你宣告並使用了某物卻從未定義它;重複定義表示你定義了它不只一次。

/* 在 header.h,是宣告 */ extern int count; int add(int a, int b); /* 在某個 .c 檔,是定義 */ int count = 0; int add(int a, int b) { return a + b; }

標頭檔宣告(宣布)共用名稱;某一個原始檔定義(建立)它們。extern 標示一個非定義的變數宣告。

函式原型是宣告,不是定義。變數定義會配置儲存空間;extern 宣告則不會。每個名字在整個程式中剛好定義一次——定義太少會得到「未定義參考」連結錯誤,太多則得到「重複定義」。

又稱
declarationdefinition宣告定義