static 聲明的變數在C語言中有兩方面的特徵:
1)、變數會被放在程式的全域儲存區中,這樣可以在下一次調用的時候還可以保持原來的賦值。這一點是它與堆棧變數和堆變數的區別。
2)、變數用static告知編譯器,自己僅僅在變數的作用範圍內可見。這一點是它與全域變數的區別。
Tips:
A.若全域變數僅在單個C檔案中訪問,則可以將這個變數修改為靜態全域變數,以降低模組間的耦合度;
B.若全域變數僅由單個函數訪問,則可以將這個變數改為該函數的靜態局部變數,以降低模組間的耦合度;
C.設計和使用訪問動態全域變數、靜態全域變數、靜態局部變數的函數時,需要考慮重入問題;
D.如果我們需要一個可重新進入的函數,那麼,我們一定要避免函數中使用static變數(這樣的函數被稱為:帶“內部儲存空間”功能的的函數)
E.函數中必須要使用static變數情況:比如當某函數的傳回值為指標類型時,則必須是static的局部變數的地址作為傳回值,若為auto類型,則返回為錯指標。
函數前加static使得函數成為靜態函數。但此處“static”的含義不是指儲存方式,而是指對函數的範圍僅局限於本檔案(所以又稱內建函式)。使用內建函式的好處是:不同的人編寫不同的函數時,不用擔心自己定義的函數,是否會與其它檔案中的函數同名。
擴充分析:術語static有著不尋常的曆史.起初,在C中引入關鍵字static是為了表示退出一個塊後仍然存在的局部變數。隨後,static在C中有了第二種含義:用來表示不能被其它檔案訪問的全域變數和函數。為了避免引入新的關鍵字,所以仍使用static關鍵字來表示這第二種含義。最後,C++重用了這個關鍵字,並賦予它與前面不同的第三種含義:表示屬於一個類而不是屬於此類的任何特定對象的變數和函數(與Java中此關鍵字的含義相同)。
全域變數、靜態全域變數、靜態局部變數和局部變數的區別變數可以分為:全域變數、靜態全域變數、靜態局部變數和局部變數。
按儲存地區分,全域變數、靜態全域變數和靜態局部變數都存放在記憶體的靜態儲存地區,局部變數存放在記憶體的棧區。
按範圍分,全域變數在整個工程檔案內都有效;靜態全域變數只在定義它的檔案內有效;靜態局部變數只在定義它的函數內有效,只是程式僅分配一次記憶體,函數返回後,該變數不會消失;局部變數在定義它的函數內有效,但是函數返回後失效。全域變數(外部變數)的說明之前再冠以static 就構成了靜態全域變數。全域變數本身就是靜態儲存方式, 靜態全域變數當然也是靜態儲存方式。 這兩者在儲存方式上並無不同。這兩者的區別雖在於非靜態全域變數的範圍是整個來源程式, 當一個來源程式由多個源檔案組成時,非靜態全域變數在各個源檔案中都是有效。 而靜態全域變數則限制了其範圍, 即只在定義該變數的源檔案內有效, 在同一來源程式的其它源檔案中不能使用它。由於靜態全域變數的範圍局限於一個源檔案內,只能為該源檔案內的函數公用, 因此可以避免在其它源檔案中引起錯誤。
從以上分析可以看出, 把局部變數改變為靜態變數後是改變了它的儲存方式即改變了它的生存期。把全域變數改變為靜態變數後是改變了它的範圍, 限制了它的使用範圍。
static函數與普通函數範圍不同。僅在本檔案。只在當前源檔案中使用的函數應該說明為內建函式(static),內建函式應該在當前源檔案中說明和定義。對於可在當前源檔案以外使用的函數,應該在一個標頭檔中說明,要使用這些函數的源檔案要包含這個標頭檔
static全域變數與普通的全域變數有什麼區別:static全域變數只初使化一次,防止在其他檔案單元中被引用;
static局部變數和普通局部變數有什麼區別:static局部變數只被初始化一次,下一次依據上一次結果值;
static函數與普通函數有什麼區別:static函數在記憶體中只有一份,普通函數在每個被調用中維持一份拷貝
全域變數和靜態變數如果沒有手工初始化,則由編譯器初始化為0。局部變數的值不可知。