今天在複習C的時候,看到關於#include語句的一個解釋,若是B 中 #include A,就是將文件A拷貝到#include A的位置中。函數
根據這個原理,因而作了一個實驗。在頭文件中定義一個變量(非靜態變量),同時聲明一個fun函數。再寫一個fun.c文件,fun.c文件中實現了fun函數,最後寫一個main.c文件調用fun函數。spa
三個文件的源代碼以下:code
test.h #include <stdio.h> #include <stdlib.h> void fun(); int com;
fun.c #include "test.h" void fun(){ com = 0; }
main.c #include "test.h" int main(){ com = 4; fun(); printf("%d\n", com); return 0; }
, 很明顯在連接的時候必然會出現「multiple definition of `com'」。通常而言也不會在頭文件中定義變量和函數。只能夠聲明變量,好比使用static能夠在頭文件中聲明變量。以下所示:orm
test.h #include <stdio.h> #include <stdlib.h> void fun(); static int com;
其餘兩個文件不作改動,編譯、連接和運行都沒有報錯,輸出結果是4. 由於靜態變量存儲靜態存儲區,可是靜態變量的做用域是一個文件,fun.c, main.c都會爲com定義一個本地變量,所以,fun對com的改動不會影響main中的com. 若是但願在fun.c中的改動對main有效果,可使用extern. ip
test.h test.h #include <stdio.h> #include <stdlib.h> void fun(); extern int com;
main.c #include "test.h" int com; int main(){ com = 4; fun(); printf("%d\n", com); return 0; }
fun.c 無須改動,此時,程序的輸出結果是0。作用域
總結如下:extern變量能夠聲明一個外部變量,使得編譯順利用過,可是在連接以後才獲得實際的變量。每個文件中定義的靜態變量都會在靜態存儲區中分別分配一個空間,靜態全局變量的做用域是該文件。在頭文件中通常不會直接定義變量和函數,僅僅做聲明。it