extern用在變量或函數的聲明前,用來講明「此變量/函數是在別處定義的,要在此處引用」。函數
extern修飾變量的聲明。post
舉例:若a.c中需引用b.c中的變量int v,能夠在a.c中聲明extern int v,而後就能夠引用變量v;須要注意的是,被引用的變量v的連接屬性必須是外spa
連接(external)的,也就是說a.c要引用到變量v,不僅是取決於在a.c中聲明extern int v,還取決於變量v自己是可以被引用到。這裏涉及到另一個話指針
題---變量的做用域。可以被其餘模塊以extern引用到的變量一般是全局變量。code
extern int v能夠放在a.c中的任何地方,好比能夠在a.c中函數func()定義的開頭處聲明extern int v,而後就能夠引用到變量v了,blog
只不過這樣只能在func()做用域中引用變量v。作用域
另一點要說明的是在b.c中須要對int v 作什麼處理嗎?那就是不能定義成靜態變量static int v,不然不能使用。原型
fileb.cit
static int A;io
int main()
{
...
}
filea.c
extern A;
{
A = A*n; //出錯
}
另外有人會有疑問爲何不在b.v文件中聲明extern A;這樣能夠表示出A的特殊性,仔細想一想真的不須要。
extern修飾函數的聲明。
本質上講,變量和函數沒有區別。函數名是指向函數二進制塊開頭處的指針。若是文件a.c要引用b.c中的函數,好比在b.c中原型是int func(int m),那麼就能夠在a.c中聲明extern int func(int m),而後就能使用func()來作任何事情。就像變量的聲明同樣,extern int func(int m)能夠放在a.c中的任何位置,而不必定非要放在a.c的文件做用域的範圍中,
對其餘模塊中函數的引用,最經常使用的方法是包含這些函數聲明的頭文件。使用extern和包含頭文件來引用函數的區別:extern的引用方式比包含頭文件要間接得多。extern的使用方法是直接了當的,想引用哪一個函數就用extern聲明哪一個函數。這大概是kiss原則的一種體現。這樣作的一個明顯的好處是,會加速程序的編譯(確切地說是預處理)的過程,節省時間。在大型C程序編譯過程當中,這種差別是很是明顯的。
此外,extern修飾符可用於指示C或者C++函數的調用規範。好比在C++中調用C庫函數,就須要在C++程序中用extern "C"聲明要引用的函數。這是給連接器使用的,告訴連接器在連接的時候用C函數規範來連接。主要緣由是C++和C程序編譯完成後再目標代碼中命名規則不一樣。
0x05
簡要例子:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int x = 0;
5 int y = 5;
6 int func1()
7 {
8 extern p, q;
9 printf("p is %d, q is %d\n", p, q);
10 return 0;
11 }
12
13 int p = 8;
14 int q = 10;
15 int main()
16 {
17 func1();
18 printf("x is %d, y is %d\n", x, y);
19 }
輸出結果: