//fileA.cpp int i; //聲明並定義i int j = 1; //聲明並定義j double max(double d1,double d2){} //定義 //fileB.cpp extern int i; //聲明i而非定義 extern int j = 2; //定義j而非聲明,會報錯,多重定義 int j; //錯誤,重定義,注意這里的j是在全局范圍內聲明 extern double max(double d1,double d2); //聲明
- external,外部鏈接屬性。非常量全局變量和自由函數(除成員函數以外的函數)均默認為外部鏈接的,它們具有全局可見性,在全局范圍不允許重名,詳情可見例子。
- internal,內部鏈接屬性。具有該屬性的類型有,const對象,constexpr對象,命令空間內的靜態對象(static objects in namespace scope)
- none,在類中、函數體和代碼塊中聲明的變量默認是具有none鏈接屬性。它和internal一樣只在當前作用域可見。
//fileA.cpp int i = 1; //聲明並定義全局變量i //fileB.cpp extern int i; //聲明i,鏈接全局變量 //fileC.cpp extern int i = 2; //錯誤,多重定義 int i; //錯誤,這是一個定義,導致多重定義 main() { extern int i; //正確 int i = 5; //正確,新的局部變量i; }
//fileA.cpp extern const int i = 1; //定義 //fileB.cpp //聲明 extern const int i;
// 聲明printf函數使用C鏈接 extern "C" int printf(const char *fmt, ...); //聲明指定的頭文件內所有的東西都使用 C 鏈接 extern "C" { #include <stdio.h> } // 聲明函數ShowChar和GetChar使用 C 鏈接 extern "C" { char ShowChar(char ch); char GetChar(void); } // 定義函數 ShowChar 和 GetChar 使用 C 鏈接 extern "C" char ShowChar(char ch) { putchar(ch); return ch; } extern "C" char GetChar(void) { char ch; ch = getchar(); return ch; } // 聲明全局變量 errno 為C鏈接 extern "C" int errno; //又比如,在程序中常見的代碼段 #ifdef __cplusplus extern "C" { #endif /**** some declaration or so *****/ #ifdef __cplusplus } #endif //這里__cplusplus是cpp中的自定義宏,定義了這個宏就表明這是一段cpp的代碼,也就是說,
//上面的代碼的含義是:如果這是一段cpp的代碼,那么加入extern "C"{和}處理其中的代碼。
- 使用extern和包含頭文件來引用函數有什么區別呢?
與include相比,extern引用另一個文件的范圍小,include可以引用另一個文件的全部內容。extern的引用方式比包含頭文件要更簡潔。extern的使用方法是直接了當的,想引用哪個函數就用extern聲明哪個函數。這樣做的一個明顯的好處是,會加速程序的編譯(確切的說是預處理)的過程,節省時間。在大型C程序編譯過程中,這種差異是非常明顯的。
參考博客:
