【1】最重要的一條:當同時編譯多個檔案時,所有未加static字首的全局變量和函數都具有全局可見性。
【2】static的第二個作用是保持變量内容的持久
存儲在靜态資料區的變量會在程式剛開始運作時就完成初始化,也是唯一的一次初始化。
如果作為static局部變量在函數内定義,它的生存期為整個源程式,但是其作用域仍與自動變量相同,隻能在定義該變量的函數内使用該變量。退出該函數後, 盡管該變量還繼續存在,但不能使用它。
#include <stdio.h>
int fun(){
static int count = ; //在第一次進入這個函數的時候,變量a被初始化為10!并接着自減1,以後每次進入該函數,a
return count--; //就不會被再次初始化了,僅進行自減1的操作;在static發明前,要達到同樣的功能,則隻能使用全局變量:
}
int count = ;
int main(void)
{
printf("global\t\tlocal static\n");
for(; count <= ; ++count)
printf("%d\t\t%d\n", count, fun());
return ;
}
【3】static的第三個作用是預設初始化為0(static變量)
最後對static的三條作用做一句話總結。首先static的最主要功能是隐藏,其次因為static變量存放在靜态存儲區,是以它具備持久性和預設值0.
【4】static的第四個作用:C++中的類成員聲明static(有些地方與以上作用重疊)
在類中聲明static變量或者函數時,初始化時使用作用域運算符來标明它所屬類,是以,靜态資料成員是類的成員,而不是對象的成員
(1)類的靜态成員函數是屬于整個類而非類的對象,是以它沒有this指針,這就導緻 了它僅能通路類的靜态資料和靜态成員函數。
(2)不能将靜态成員函數定義為虛函數。
(3)由于靜态成員聲明于類中,操作于其外,是以對其取位址操作,就多少有些特殊 ,變量位址是指向其資料類型的指針 ,函數位址類型是一個“nonmember函數指針”。
(4)由于靜态成員函數沒有this指針,是以就差不多等同于nonmember函數,結果就 産生了一個意想不到的好處:成為一個callback函數,使得我們得以将C++和C-based X W indow系統結合,同時也成功的應用于線程函數身上。 (這條沒遇見過)
(5)static并沒有增加程式的時空開銷,相反她還縮短了子類對父類靜态成員的通路 時間,節省了子類的記憶體空間。
6)靜态資料成員在<定義或說明>時前面加關鍵字static。
(7)靜态資料成員是靜态存儲的,是以必須對它進行初始化。 (程式員手動初始化,否則編譯時一般不會報錯,但是在Link時會報錯誤)
(8)靜态成員初始化與一般資料成員初始化不同:
初始化在類體外進行,而前面不加static,以免與一般靜态變量或對象相混淆;
初始化時不加該成員的通路權限控制符private,public等;
初始化時使用作用域運算符來标明它所屬類;
是以我們得出靜态資料成員初始化的格式:
<資料類型><類名>::<靜态資料成員名>=<值>
(9)為了防止父類的影響,可以在子類定義一個與父類相同的靜态變量,以屏蔽父類的影響。這裡有一點需要注意:我們說靜态成員為父類和子類共享,但我們有重複定義了靜态成員,這會不會引起錯誤呢?不會,我們的編譯器采用了一種絕妙的手法:name-mangling 用以生成唯一的标志。