static使用總結

2021-05-26 01:28:31 字數 3299 閱讀 6877

static關鍵字是c, c++中都存在的關鍵字, 它主要有三種使用方式, 其中前兩種在c/c++語言中使用, 第三種只在c++中使用(c,c++中具體細微操作不盡相同, 本文以c++為準).

(1)區域性靜態變數

(2)外部靜態變數/函式

(3)靜態資料成員/成員函式

一、static變數

1. 靜態區域性變數

靜態區域性變數屬於靜態儲存方式,它在函式內定義,生存期為整個源程式,但是其作用域仍與自動變數相同,只能在定義該變數的函式內使用該變數。static分配在靜態儲存區, 在程式整個執行期間都不釋放。static區域性變數在所處模組在初次執行時進行初始化工作, 且只操作一次。對於區域性靜態變數, 如果不賦初值, 編譯期會自動賦初值0或空字元。

(1)static區域性變數的」記憶性」

所謂」記憶性」是指在兩次函式呼叫時, 在第二次呼叫進入時, 能保持第一次呼叫退出時的值. 

a=0a=1

(2)「生存期」全域性性和唯一性。

普通的local變數的儲存空間分配在stack上, 因此每次呼叫函式時, 分配的空間都可能不一樣, 而static具有全域性唯一性的特點, 每次呼叫時, 都指向同一塊記憶體, 這就造成乙個很重要的問題 ---- 不可重入性!!!

這樣在多執行緒程式設計或遞迴程式設計中, 要特別注意這個問題。

(不可重入性的例子可以參見(影印版)第103-105頁)

下面針對示例程式二, 分析在多執行緒情況下的不安全性。

① const char * iptostr(uint32 ipaddr)

② 假設現在有兩個執行緒a,b執行期間都需要呼叫iptostr()函式, 將32位的ip位址轉換成點分10進製的字串形式. 現a先獲得執行機會, 執行iptostr(), 傳入的引數是0x0b090a0a, 順序執行完應該返回的指標儲存區內容是:」10.10.9.11」, 現執行到⑥時, 失去執行權, 排程到b執行緒執行, b執行緒傳入的引數是0xa8a8a8c0, 執行至⑦, 靜態儲存區的內容是192.168.168.168. 當再排程到a執行時, 從⑥繼續執行, 由於strbuff的全域性唯一性, 內容已經被b執行緒沖掉, 此時返回的將是192.168.168.168字串, 不再是10.10.9.11字串。

2.靜態全域性變數

全域性變數(外部變數)的說明之前再冠以static 就構成了靜態的全域性變數。但此處「static」的含義不是指儲存方式,而是指對函式的作用域僅侷限於本檔案(所以又稱內部函式)。注意此時, 對於外部(全域性)變數, 不論是否有static限制, 它的儲存區域都是在靜態儲存區, 生存期都是全域性的. 此時的static只是起作用域限制作用, 限定作用域在本模組(檔案)內部.

二、static 函式

如果在乙個原始檔中定義的函式,只能被本檔案中的函式呼叫,而不能被同一程式其它檔案中的函式呼叫,這種函式稱為內部函式。定義乙個內部函式,只需在函式型別前再加乙個「static」關鍵字即可,如下所示:

static    函式型別    函式名(函式引數表)

同靜態全域性變數的static一樣,此處「static」的含義不是指儲存方式,而是指對函式的作用域僅侷限於本檔案。

使用內部函式的好處是:不同的人編寫不同的函式時,不用擔心自己定義的函式,是否會與其它檔案中的函式同名,因為同名也沒有關係。

[extern]    函式型別    函式名(函式引數表)

呼叫外部函式時,需要對其進行說明:

[extern]    函式型別    函式名(引數型別表)[,函式名2(引數型別表2)……];

例項見上面的例子。

三、靜態資料成員/成員函式(c++特有)

1 靜態資料成員

c++重用了這個關鍵字,並賦予它與前面不同的第三種含義:表示屬於乙個類而不是屬於此類的任何特定物件的變數和函式。因為它是對整個類來說是唯一的, 因此不可能屬於某乙個例項物件的。使用靜態資料成員可以節省記憶體,因為它是所有物件所公有的,因此,對多個物件來說,靜態資料成員只儲存一處,供所有物件共用。靜態資料成員的值對每個物件都是一樣,但它的值是可以更新的。只要對靜態資料成員的值更新一次,保證所有物件訪問更新後的相同的值,這樣可以提高時間效率。

靜態資料成員的使用方法和注意事項如下:

0、靜態資料成員和普通資料成員一樣遵從public,protected,private訪問規則;private,protected 的static成員雖然可以在類外初始化,但是不能在類外被訪問。

1、靜態資料成員在定義或說明時前面加關鍵字static。

2、靜態資料成員是靜態儲存的,它是靜態生存期,必須對它進行初始化。static成員變數的初始話是在類外,此時不能再帶上static的關鍵字。靜態成員初始化與一般資料成員初始化不同。靜態資料成員初始化的格式如下:

《資料型別》《類名》::《靜態資料成員名》=《值》

3、引用靜態資料成員時,採用如下格式:

《類名》::《靜態成員名》

類的靜態資料成員有兩種訪問形式:

<類物件名>.<靜態資料成員名> 或 <類型別名>::<靜態資料成員名>

如果靜態資料成員的訪問許可權允許的話(即public的成員),可在程式中,按上述格式來引用靜態資料成員 ;

執行結果:54

同全域性變數相比,使用靜態資料成員有兩個優勢:

靜態資料成員沒有進入程式的全域性名字空間,因此不存在與程式中其它全域性名字衝突的可能性;

可以實現資訊隱藏。靜態資料成員可以是private成員,而全域性變數不能;

2、靜態成員函式

普通的成員函式一般都隱含了乙個this指標,this指標指向類的物件本身,因為普通成員函式總是具體的屬於某個類的具體物件的。通常情況下,this是預設的。如函式fn()實際上是this->fn()。但是與普通函式相比,靜態成員函式由於不是與任何的物件相聯絡,因此它不具有this指標。從這個意義上講,它無法訪問屬於類物件的非靜態資料成員,也無法訪問非靜態成員函式,它只能呼叫其餘的靜態成員函式。下面舉個靜態成員函式的例子。

#include class myclass

;int myclass::sum=0;//定義並初始化靜態資料成員

myclass::myclass(int a,int b,int c)

void myclass::getsum() //靜態成員函式的實現

{// cout<)為乙個類的物件或指向類物件的指標呼叫靜態成員函式,也可以直接使用如下格式:

<類名>::<靜態成員函式名>(<參數列>)

呼叫類的靜態成員函式。

static 使用總結

第 一 類靜態成員 1.初始化 靜態成員變數必須初始化 類的靜態成員可以是公有的也可以是私有的 無 私必須在外部初始化。如 int a i 1 必須這樣初始化 初始化完畢才能賦值 2 訪問 公有的外部可以直接訪問 a b 5 私有的則不可以。3 類成員間呼叫 類成員函式可以呼叫靜態成員變數和靜態成員...

static的使用總結

全域性變數前加上關鍵字static,全域性變數就定義成乙個全域性靜態變數.全域性靜態變數儲存在靜態儲存區,在整個程式執行期間一直存在。全域性靜態變數在程式執行之前就存在。初始化 未經初始化的全域性靜態變數會被自動初始化為0 自動物件的值是任意的,除非他被顯式初始化 作用域 全域性靜態變數在宣告他的檔...

static關鍵字使用總結

static使用特點如下 1 引用這個方法時,可以使用物件名做字首,也可以使用類名做字首 2 static方法不能被覆蓋,也就是說,這個類的子類,不能有相同名 相同引數的方法 3 static方法只能訪問static方法,不能訪問非static方法,但非static方法可以訪問static方法 4 ...