1.extern??
? extern 是?來聲明外部符號的,如果?個全局的符號在A?件中定義的,在B?件中想使?,就可以使? extern 進?聲明,然后使?。
? 即在一個源文件中想要使用另一個源文件,即可通過這個extern來聲明使用。
2.static
??static 是 靜態的 的意思,可以?來:
? 修飾局部變量
? 修飾全局變量
? 修飾函數
在講解 static 和 extern 之前再講?下:作?域和?命周期。
作用域(scope)是程序設計概念,通常來說,?段程序代碼中所?到的名字并不總是有效(可?)的,?限定這個名字的可?性的代碼范圍就是這個名字的作?域。
1. 局部變量的作?域是變量所在的局部范圍。
2. 全局變量的作?域是整個?程(項?)。
?命周期指的是變量的創建(申請內存)到變量的銷毀(收回內存)之間的?個時間段。
1. 局部變量的?命周期是:進?作?域變量創建,?命周期開始,出作?域?命周期結束。
2. 全局變量的?命周期是:整個程序的?命周期。
A.static 修飾局部變量:
//代碼1 #include <stdio.h>
void test()
{int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for(i=0; i<5; i++){test();}return 0; }
//代碼2 #include <stdio.h>
void test()
{//static修飾局部變量static int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for(i=0; i<5; i++){test();}return 0; }
? 對?代碼1和代碼2的效果,理解 static 修飾局部變量的意義。
? 代碼1的test函數中的局部變量i是每次進?test函數先創建變量(?命周期開始)并賦值為0,然后
++,再打印,出函數的時候變量?命周期將要結束(釋放內存)。
? 代碼2中,我們從輸出結果來看,i的值有累加的效果,其實 test函數中的i創建好后,出函數的時候是不會銷毀的,重新進?函數也就不會重新創建變量,直接上次累積的數值繼續計算。
?這里我們可以了解一下內存,下面是我的獨家筆記哦:

?
? 結論:static修飾局部變量改變了變量的?命周期,?命周期改變的本質是改變了變量的存儲類型,本來?個局部變量是存儲在內存的棧區的,但是被 static 修飾后存儲到了靜態區。存儲在靜態區的變 量和全局變量是?樣的,?命周期 就和程序的?命周期?樣了,只有程序結束,變量才銷毀,內存才 回收。但是作?域不變的。
? 使?建議:未來?個變量出了函數后,我們還想保留值,等下次進?函數繼續使?,就可以使?static修飾。
B.static修飾全局變量
這里是在一個大文件中有多個源文件
?代碼1
add.c
int g_val = 2018;
test.c
#include <stdio.h>
extern int g_val;
int main()
{printf("%d\n", g_val);return 0;
}
?代碼2
add.c
static int g_val = 2018;
test.c
#include <stdio.h>
extern int g_val;
int main()
{printf("%d\n", g_val);return 0;
}
? 對比上述兩個不同的代碼,我們可以得到結論:
? ?個全局變量被static修飾,使得這個全局變量只能在本源?件內使?,不能在其他源?件內使?。 本質原因是全局變量默認是具有外部鏈接屬性的,在外部的?件中想使?,只要適當的聲明就可以使?;但是全局變量被 static 修飾之后,外部鏈接屬性就變成了內部鏈接屬性,只能在??所在的源?件內部使?了,其他源?件,即使聲明了,也是?法正常使?的。
? 使?建議:如果?個全局變量,只想在所在的源?件內部使?,不想被其他?件發現,就可以使?static修飾。
C.static 修飾函數
? static 修飾函數與修飾全局變量是一樣的道理的。
代碼1
add.c
int Add(int x, int y)
{return x+y;
}
test.c
#include <stdio.h>
extern int Add(int x, int y);
int main()
{printf("%d\n", Add(2, 3));return 0; }
代碼2
add.c
static int Add(int x, int y)
{return x+y;
}
test.c
#include <stdio.h>
extern int Add(int x, int y);
int main()
{printf("%d\n", Add(2, 3));return 0; }
? 對比運行結果有:代碼1是能夠正常運?的,但是代碼2就出現了鏈接錯誤。
結論:
? 其實 static 修飾函數和 static修飾全局變量是?模?樣的,?個函數在整個?程都可以使?,
被static修飾后,只能在本?件內部使?,其他?件?法正常的鏈接使?了。 本質是因為函數默認是具有外部鏈接屬性,具有外部鏈接屬性,使得函數在整個?程中只要適當的聲明就可以被使?。但是被 static 修飾后變成了內部鏈接屬性,使得函數只能在??所在源?件內部使?。
? 使?建議:?個函數只想在所在的源?件內部使?,不想被其他源?件使?,就可以使? static 修飾。