轉自:http://blog.csdn.net/wanglongfei_hust/article/details/10011503ios
static關鍵字有三種使用方式,其中前兩種只指在C語言中使用,第三種在C++中使用。c++
1. 局部靜態變量(C)
2. 外部靜態變量/函數(C)
3. 靜態數據成員/成員函數(C++)
1、 局部靜態變量
局部變量按照存儲形式能夠分爲三種,分別是auto、static、register。
與auto類型(普通)局部變量相比,static有三點不一樣:
1. 存儲空間分配不一樣
auto類型分配在棧上,屬於動態存儲類別,佔動態存儲空間,函數調用結束後自動釋放;
static類型分配在靜態存儲區,在程序整個運行期間都不釋放;
二者做用域相同,可是生存期不一樣。
2. static局部變量在初次運行時進行初始化工做,且只初始化一次。
3. 對於局部靜態變量,若是不賦初值,編譯期會自動賦初值0或者空;
auto類型的初值是不肯定的。
對於C++的類對象例外,class的對象實例若是不初始化,則會自動調用默認構造函數,不論是不是static類型。
特色:static局部變量的「記憶性」與生存期的「全局性」
所謂「記憶性」是指在兩次函數調用時,在第二次調用進入時,能保持第一次調用退出時的值。
示例程序一
多線程
運行結果:函數
a=1this
a=2spa
請按任意鍵繼續. . ..net
應用:利用「記憶性」記錄函數調用的次數(示例程序一)
利用生存期的」全局性「改善return a pointer / reference to a local object的問題,local object的問題在於退出函數時,生存期就結束,局部變量就會被銷燬;利用static就能夠延長局部變量的生存期。
注意事項:
1. 「記憶性」是程序運行很重要的一點就是可重複性,而static變量的「記憶性」破壞了可重複性,形成不一樣時刻同一函數的運行結果不一樣。
2. 「生存期」全局性和惟一性。 普通的局部變量在棧上分配空間,所以每次調用函數時,分配的空間均可能不同,而static具備全局惟一性的特色,每次調用時都指向同一塊內存,這就形成一個很重要的問題---不可重入性!!!
在多線程或者遞歸程序中要特別注意。
2、 外部靜態變量/函數
在C中static的第二種含義:用來表示不能被其它文件訪問的全局變量和函數。
此處static的含義是指對函數的做用域僅僅侷限於本文件(因此又稱爲內部函數)。
注意:對於外部(全局)變量,不管是否有static限制,它的存儲區域都是在靜態存儲區,生存期都是全局的,此時的static只是起做用域限制做用,限制做用域在本文件內部。
使用內部函數的好處是:不一樣的人編寫不一樣的函數時,不用擔憂函數同名問題。
示例程序二
線程
3、 靜態數據成員/成員函數(C++特有)指針
C++重用了這個關鍵字,它表示屬於一個類而不是屬於此類的任何特定的對象的變量和函數。
靜態類成員包括靜態數據成員和靜態函數成員。
1. 靜態數據成員
類體中的數據成員的聲明前加上static關鍵字,該數據成員就成爲了該類的靜態數據成員。和其餘數據成員同樣,靜態數據成員也遵照public/protected/private訪問規則。同時靜態數據成員還具備如下特色。
1) 靜態數據成員的定義
靜態數據成員其實是類域中的全局變量。因此,靜態數據成員的定義(初始化)不該該被放在頭文件中。其定義方式與全局變量相同。舉例以下:
code
注:不要試圖在頭文件中定義(初始化)靜態數據成員。在大多數狀況下,這會引發重複定義。即便加上#ifndef #define #endif或者#pragma once也不行。
2) 靜態數據成員被類的全部對象所共享,包括該類的派生類的對象。
3) 靜態數據成員能夠成爲成員函數的可選參數,而普通數據成員則不能夠。
4)★靜態數據成員的類型能夠是所屬類的類型,而普通數據成員則不能夠。普通數據成員的只能聲明爲所屬類類型的指針或引用。舉例以下:
5) 靜態數據成員的值在const成員函數中能夠被合法的改變。舉例以下:
2. 靜態成員函數
1).靜態成員函數的地址可用普通函數指針儲存,而普通成員函數地址須要用類成員函數指針來儲存。舉例以下:
2).靜態成員函數不能夠調用類的非靜態成員。由於靜態成員函數不含this指針。
3).靜態成員函數不能夠同時聲明爲 virtual、const、volatile函數。舉例以下:
最後要說的一點是,靜態成員是能夠獨立訪問的,也就是說,無須建立任何對象實例就能夠訪問。