extern和static釋析
注意:下文中提到的“變量”或“函數(shù)”均指的是“全局”的,同時(shí)也請(qǐng)大家務(wù)必注意聲明和定義的措辭(實(shí)際上,我這么說是有錯(cuò)誤的,因?yàn)楹瘮?shù)就沒有全局和局部之分,其實(shí)函數(shù)都是全局的,例如我們?cè)贏文件中定義了一個(gè)函數(shù)void fun(){},在B文件中直接就可以利用,[extern] void fun(); void main(){fun();})
extern g_A;//這是聲明,而且是一個(gè)int型的聲明
extern double g_A;//這是聲明
extern double g_A=234.34;//這是聲明+定義
extern用于聲明變量時(shí),如果不指出變量的類型,則默認(rèn)為int,如果不是int的,必須顯示指出變量的類型,否則出錯(cuò)。
extern實(shí)際上只對(duì)變量有用,對(duì)函數(shù)而言,只是個(gè)幌子(能夠更加清晰明了的讓我們知道也讓編譯器知道該函數(shù)可以用于“外交”),沒有實(shí)質(zhì)性的作用,以后記住了,看到extern和函數(shù)扯上關(guān)系,你理都不用理,直接把它拿掉就OK了。但是它還是有那么一點(diǎn)用的,既然“存在的就是合理的”,那么它必然有點(diǎn)用啦,利用它可以在程序中取代include “*.h”來聲明函數(shù),在一些復(fù)雜的項(xiàng)目中,我比較習(xí)慣在所有的函數(shù)聲明前添加extern修飾。
本質(zhì)上,我認(rèn)為,函數(shù)可以將聲明和定義分開,而變量就不行了,因此只能借助于extern來實(shí)現(xiàn)這一點(diǎn),要是變量也能將聲明和定義分開,或許extern根本就不該活在這個(gè)世上。
extern可以被寫在變量/函數(shù)的聲明/定義處,但是標(biāo)準(zhǔn)的用法應(yīng)該只是將其寫在聲明處,寫在定義處只不過為了再次強(qiáng)調(diào)或直觀明了而已。
因此利用extern的威力,我們可以將變量的聲明放在頭文件中(因?yàn)檎l都知道頭文件就怕出現(xiàn)變量或函數(shù)的定義,一旦被多次包含就會(huì)出現(xiàn)重復(fù)定義,編譯器不懼怕重復(fù)聲明,但懼怕重復(fù)定義,你這么寫“void zenmehui();void zenmehui();void zenmehui();void main(){zenmehui();}”肯定沒問題,不信你自己試試看)。
=====================================================================
與extern相對(duì)的是static,大家都熟悉static代表靜態(tài)的意思,卻很少有人注意到它還有“內(nèi)部”(即表示該變量只供本文件內(nèi)部使用)的意思。不過可以肯定的是,只要是用static修飾的變量,都會(huì)被放在內(nèi)存中的“靜態(tài)存儲(chǔ)區(qū)”來存儲(chǔ)(我通常會(huì)把生成的可執(zhí)行文件分成靜態(tài)存儲(chǔ)區(qū)、棧區(qū)、代碼區(qū)、一份含有所有變量和函數(shù)的清單《清單中的每一項(xiàng)會(huì)指向?qū)?yīng)的變量或函數(shù)存儲(chǔ)的地方》)。
靜態(tài)存儲(chǔ)區(qū)一般會(huì)放置:全局變量(又分為純粹全局的和被static修飾的僅供文件內(nèi)部使用的兩種)、static修飾的局部變量。
其實(shí)這些有關(guān)static的討論都是基于C語言的,在C++中新增了類的概念,類里使用的static在概念和意義上都有別去傳統(tǒng)的C語言,靜態(tài)的成員變量被存儲(chǔ)在類的靜態(tài)存儲(chǔ)區(qū)中,可以不必等待類實(shí)例化就使用,靜態(tài)的成員函數(shù)表明該函數(shù)只能使用類中的靜態(tài)成員變量和其他靜態(tài)成員函數(shù)。
現(xiàn)在我希望大家今后不要再一看到static就把它完全等價(jià)于“靜態(tài)”之意了,總結(jié)一下:
static修飾函數(shù):
在修飾非成員函數(shù)時(shí)表示該函數(shù)不是全局函數(shù),而僅供本文件使用;
在修飾成員函數(shù)時(shí),表示該函數(shù)只能調(diào)用類的靜態(tài)成員變量并且該方法可以不必經(jīng)由實(shí)例化的類對(duì)象就能夠應(yīng)用;
static修飾變量:
修飾全局變量時(shí),該變量只能供本文件內(nèi)部使用;
修飾成員變量時(shí),該變量成為類變量,存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū)中,不經(jīng)過類實(shí)例就可以訪問該變量;
修飾局部變量時(shí),該變量在函數(shù)第一次被調(diào)用時(shí)初始化,并將其存放到靜態(tài)存儲(chǔ)區(qū),函數(shù)退出后變量值保持不變,下一次進(jìn)入函數(shù)時(shí)將跳過對(duì)它的初始化,它的生命周期直到程序退出。
最后,要說明的是,static變量在全局中只有一份,不會(huì)有多份拷貝。