關於C/C++中static症結字的感化總結。本站提示廣大學習愛好者:(關於C/C++中static症結字的感化總結)文章只能為提供參考,不一定能成為您想要的結果。以下是關於C/C++中static症結字的感化總結正文
1.先來引見它的第一條也是最主要的一條:隱蔽。(static函數,static變量都可)
當同時編譯多個文件時,一切未加static前綴的全局變量和函數都具有全局可見性。
舉例來講明。同時編譯兩個源文件,一個是a.c,另外一個是main.c。
//a.c
char a = 'A'; // global variable
void msg()
{
printf("Hello\n");
}
//main.c
int main()
{
extern char a; // extern variable must be declared before use
printf("%c ", a);
(void)msg();
return 0;
}
法式的運轉成果是:
A Hello
為何在a.c中界說的全局變量a和函數msg能在main.c中應用?後面說過,一切未加static前綴的全局變量和函數都具有全局可見性,其它的源文件也能拜訪。此例中,a是全局變量,msg是函數,而且都沒有加static前綴,是以關於別的的源文件main.c是可見的。
假如加了static,就會對其它源文件隱蔽。例如在a和msg的界說前加上static,main.c就看不到它們了。應用這一特征可以在分歧的文件中界說同名函數和同名變量,而不用擔憂定名抵觸。static可以用作函數和變量的前綴,關於函數來說,static的感化僅限於隱蔽.
2.static的第二個感化是堅持變量內容的耐久。(static變量中的記憶功效和全局生計期)
存儲在靜態數據區的變量會在法式剛開端運轉時就完成初始化,也是獨一的一次初始化。共有兩種變量存儲在靜態存儲區:全局變量和static變量,只不外和全局變量比起來,static可以掌握變量的可見規模,說究竟static照樣用來隱蔽的。固然這類用法不罕見
PS:假如作為static部分變量在函數內界說,它的生計期為全部源法式,然則其感化域仍與主動變量雷同,只能在界說該變量的函數內應用該變量。加入該函數後, 雖然該變量還持續存在,但不克不及應用它。
法式舉例:
#include <stdio.h>
int fun(){
static int count = 10; //在第一次進入這個函數的時刻,變量a被初始化為10!並接著自減1,今後每次進入該函數,a
return count--; //就不會被再次初始化了,僅停止自減1的操作;在static創造前,要到達異樣的功效,則只能應用全局變量:
}
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;
}
法式的運轉成果是:
global local static
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
--基於以上兩點可以得出一個結論:把部分變量轉變為靜態變量後是轉變了它的存儲方法即轉變了它的生計期。把全局變量轉變為靜態變量後是轉變了它的感化域, 限制了它的應用規模。是以static 這個解釋符在分歧的處所所起的感化是分歧的。
3.static的第三個感化是默許初始化為0(static變量)
其實全局變量也具有這一屬性,由於全局變量也存儲在靜態數據區。在靜態數據區,內存中一切的字節默許值都是0x00,某些時刻這一特色可以削減法式員的任務量。好比初始化一個稀少矩陣,我們可以一個一個地把一切元素都置0,然後把不是0的幾個元素賦值。假如界說成靜態的,就省去了一開端置0的操作。再好比要把一個字符數組當字符串來用,但又認為每次在字符數組末尾加‘\0';太費事。假如把字符串界說成靜態的,就省去了這個費事,由於那邊原來就是‘\0';無妨做個小試驗驗證一下。
#include <stdio.h>
int a;
int main()
{
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的第四個感化: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 用以生成獨一的標記。