c語言中static關鍵字和extern關鍵字

看extern關鍵字和static關鍵字之前請看一下之前寫的一篇博客,便於更深的理解:http://blog.csdn.net/baidu_32134295/article/details/53078872

1.static關鍵字

        當它用於函數定義時,或用於代碼塊之外的變量聲明時,static關鍵字用於修改標識符的鏈接屬性,從external改爲internal,但標識符的存儲類型和作用域不受影響。用這種方式聲明的函數或者變量只能在聲明它們的源文件中訪問。

當它用於代碼塊內部的變量聲明時,static關鍵字用於修改變量的存儲類型從自動變量改爲靜態變量,但變量的鏈接屬性和作用域不受影響。用這種方式聲明的變量在程序執行之前創建,並在程序的整個執行期間一直存在,而不是每次在代碼塊開始執行時創建,在代碼塊執行完畢後銷燬。

2.extern關鍵字

具有external鏈接屬性的實體在其他語言的術語裏稱爲全局(global)實體,所有源文件中的所有函數均可以訪問它。只要變量並非聲明於代碼塊或函數定義內部,它在缺省情況下的鏈接屬性即爲external。如果一個變量聲明於代碼塊內部,在它前面添加extern關鍵字將使它所引用的是全局變量而非局部變量

具有external鏈接屬性的實體總是具有靜態存儲類型。全局變量在程序開始執行前創建,並在程序整個執行過程中始終存在。從屬於函數的局部變量在程序開始執行時創建,在函數執行完畢後銷燬,但用於執行函數的機器指令在程序的聲明週期內一直存在。

局部變量由函數內部使用,不能被其他函數通過名字引用,他在缺省情況下的存儲類型爲自動,這是基於兩個原因:其一,當這些變量需要時才爲它們分配存儲,這樣可以減少內存的總需求量。其二,在堆棧上爲它們分配存儲可以有效的實現遞歸。如果你覺得讓變量的值在函數的多次調用中始終保持原先的值非常重要的話,你可以修改它的存儲類型,把它從自動變量改爲靜態變量。


                                                                                   作用域、鏈接屬性和存儲類型總結圖

下面用代碼例子進行說明:

1 int  a = 5; //鏈接屬性爲external
2 extern int b; //鏈接屬性爲external
3 static int c; //static關鍵字修改了c的缺省鏈接屬性,把它改爲internal -->由此變量c只能由這個源文件訪問
/*這裏變量a、b、c的存儲類型爲靜態,表示它們並不是存儲在堆棧中。因此,這些變量在程序執行之前創建,並一直保持它們的值,直到程序結束
這些變量的作用域一直延伸到這個源文件結束爲止,但第7行和第13行聲明的局部變量a和b在那部分程序中將隱藏同名的靜態變量。因此,這三個變量的
作用域爲:
a 第1行至12行,第17行至29行
b 第 2行至6行,第25行至29行
c 第3行至29行
*/
4 int d(int e)//d在缺省情況下具有external鏈接屬性,所以其他源文件只要在文件上存在d的原型,就可以調用d。對於函數而言,存儲類型並不是問題,因爲代碼總是存儲在靜態內存中。
5 {
6 int f = 15;
7 refister int b;
8 static int g = 20;
9 extern int a;
10 ...
11 {
12 int e;// 12-13行代碼塊聲明局部變量。他們都具有自動存儲類型,它們的作用域到16行,這些變量和先前聲明的a和e不同,而且由於名字衝突
13 int a;//這個代碼塊中以前聲明的同名變量是不能被訪問的
14 extern int h;//全局變量h在這個代碼塊中可以被訪問。它存儲於靜態內存中。這是唯一一個必須使用關鍵字extern的聲明,沒有它,h將變成另一個局部變量
15 ...
16 }
17 ...
18 {
19 int x;
20 int e;//這個e和參數e是不同的變量
21 ...
22 }
23 ...
24 }


25 static int i()//i爲靜態鏈接屬性。可以防止它被這個源文件之外的任何函數調用。I的作用域從它聲明的位置直到這個源文件結束。

// 函數d不可以調用函數i ,因爲在d 之前不存在i的原型
26 {
27 ...
28 }


29 ...

發佈了77 篇原創文章 · 獲贊 110 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章