static 這個關鍵字,我感受對不少初級程序源和剛接觸程序的同窗來講,可能都沒有徹底理解它的含義。至少對我來講對它的認識不是很清楚。所以對它在次總結一下。主要做爲本身的備忘錄。html
1.static關鍵字的第一特性:隱藏ios
static 在修飾變量時分爲全局變量和局部變量,都存在靜態存儲區域。程序員
static全局變量:做用域是從定義的位置開始到整個所在cpp文件結束,其餘cpp文件都不能使用static定義的變量,在同一個cpp文件中,在定義前使用要用extern關鍵字。所以static修飾變量會被隱藏在一個cpp文件裏。數組
static 局部變量:做用域只在一個函數的內部使用,static局部變量是靜態存儲,所以在函數退出後,仍然保存值,再次進入函數時,static局部變量使用上次的值。函數
在局部變量前,加上關鍵字static,該變量就被定義成爲一個靜態局部變量。 咱們先舉一個靜態局部變量的例子,以下: spa
//Example 3 #include <iostream.h> void fn(); void main() { fn(); fn(); fn(); } void fn() { static n=10; cout<<n<<endl; n++; }
一般,在函數體內定義了一個變量,每當程序運行到該語句時都會給該局部變量分配棧內存。但隨着程序退出函數體,系統就會收回棧內存,局部變量也相應失效。可是有時候咱們須要在兩次調用之間對變量的值進行保存。一般的想法是定義一個全局變量來實現。但這樣一來,變量已經再也不屬於函數自己了,再也不僅受函數的控制,給程序的維護帶來不便。 靜態局部變量正好能夠解決這個問題。靜態局部變量保存在全局數據區,而不是保存在棧中,每次的值保持到下設計
static 修飾函數:函數前加 static 使得函數成爲靜態函數。但此處「static」的含義不是指存儲方式,而是指對函數的做用域僅侷限於本文件(因此又稱內部函數)。使用內部函數的好處是:不一樣的人編寫不一樣的函數時,不用擔憂本身定義的函數,是否會與其它文件中的函數同名。指針
2.static的第二個做用是:保持變量內容的持久 code
存儲在靜態數據區的變量會在程序剛開始運行時就完成初始化,也是惟一的一次初始化。共有兩種變量存儲在靜態存儲區:全局變量和static變量,只不過和全局變量比起來,static能夠控制變量的可見範圍,說到底static仍是用來隱藏的。雖然這種用法不常見,但我仍是舉一個例子。 htm
#include <stdio.h> int fun(void){ static int count = 10; // 事實上此賦值語句歷來沒有執行過,僅在程序初始化時,初始static局部變量count=10,之後就再也不執行。 return count--; } int count = 1; int main(void) { printf("global\t\tlocal static\n"); for(; count <= 10; ++count) printf("%d\t\t%d\n", count, fun()); return 0; }
3. static的第三個做用是默認初始化爲0.
其實全局變量也具有這一屬性,由於全局變量也存儲在靜態數據區
在靜態數據區,內存中全部的字節默認值都是0x00,某些時候這一特色能夠減小程序員的工做量。好比初始化一個稀疏矩陣,咱們能夠一個一個地把全部元素都置0,而後把不是0的幾個元素賦值。若是定義成靜態的,就省去了一開始置0的操做。再好比要把一個字符數組當字符串來用,但又以爲每次在字符數組末尾加‘\0’太麻煩。若是把字符串定義成靜態的,就省去了這個麻煩,由於那裏原本就是‘\0’。不妨作個小實驗驗證一下。
#include <stdio.h> int a; int main(void){ int i; static char str[10]; printf("integer: %d; string: (begin)%s(end)", a, str); return 0; }
程序的運行結果以下integer: 0; string: (begin)(end)
最後對static的三條做用作一句話總結。首先static的最主要功能是隱藏,其次由於static變量存放在靜態存儲區,因此它具有持久性和默認值0.
4. 用static聲明的函數和變量小結
static 聲明的變量在C語言中有兩方面的特徵:
1)、變量會被放在程序的全局存儲區中,這樣能夠在下一次調用的時候還能夠保持原來的賦值。這一點是它與堆棧變量和堆變量的區別。
2)、變量用static告知編譯器,本身僅僅在變量的做用範圍內可見。這一點是它與全局變量的區別。
Tips:
A.若全局變量僅在單個C文件中訪問,則能夠將這個變量修改成靜態全局變量,以下降模塊間的耦合度;
B.若全局變量僅由單個函數訪問,則能夠將這個變量改成該函數的靜態局部變量,以下降模塊間的耦合度;
C.設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,須要考慮重入問題;
D.若是咱們須要一個可重入的函數,那麼,咱們必定要避免函數中使用static變量(這樣的函數被稱爲:帶「內部存儲器」功能的的函數)
E.函數中必需要使用static變量狀況:好比當某函數的返回值爲指針類型時,則必須是static的局部變量的地址做爲返回值,若爲auto類型,則返回爲錯指針。
函數前加static使得函數成爲靜態函數。但此處「static」的含義不是指存儲方式,而是指對函數的做用域僅侷限於本文件(因此又稱內部函數)。使用內部函數的好處是:不一樣的人編寫不一樣的函數時,不用擔憂本身定義的函數,是否會與其它文件中的函數同名。
5.static 描述類的靜態變量和函數:
C++重用了這個關鍵字,並賦予它與前面不一樣的第三種含義:表示屬於一個類而不是屬於此類的任何特定對象的變量和函數(與Java中此關鍵字的含義相同)。