file1.c:int g_val = 100; (定義)
file1.h:extern int g_val; (聲明)
file2.c:#include "file1.h" ... g_val = 200; (使用)
extern 告訴編譯器「此變量在別處定義」,連結器負責解析地址。extern void foo(); // 等價於
void foo(); // extern 為函數默認存儲類別,可寫可不寫
作用:提示「此函數可能在其他源檔定義」。若同專案內,直接包含頭文件更清晰。
/* C++ 源檔中調用 C 庫 */
#ifdef __cplusplus
extern "C" {
#endif
void c_library_func(void);
#ifdef __cplusplus
}
#endif
原理:C++ 編譯器對函數名進行 Name Mangling(如 _Z13c_library_funcv),而 C 編譯器不會。extern "C" 告訴 C++ 連結器以 C 命名規則尋找符號。
「用頭文件聲明全域變量 vs 用 extern 声明,拼寫錯誤時錯誤發現時機不同。」
extern 声明拼錯 → 連結期 報錯(符號未定義),編譯通過但無法生成可執行檔。/* print_extern.c */
#include <stdio.h>
void print_extern() { printf("hello extern test!!\n"); }
/* extern_test.c */
#include <stdio.h>
extern void print_extern(); // 可省略 extern
int main() { print_extern(); }
/* 編譯鏈接 */
gcc -c print_extern.c -o print_extern.o
gcc print_extern.o extern_test.c -o extern_test
./extern_test