前段時(shí)間在蕭大的技術(shù)社區(qū)http://cocode.cc/上看到一個(gè)問(wèn)題(http://cocode.cc/t/topic/4213)提問(wèn)者是個(gè)初學(xué)者易核,問(wèn)的是C語(yǔ)言中關(guān)于變量的外部鏈接的問(wèn)題函似,其實(shí)就是extern關(guān)鍵字的用法爽柒,回答了一下小白的問(wèn)題如暖,同時(shí)在回答問(wèn)題的過(guò)程中自己也學(xué)到了新的東西赔退,便有了把這個(gè)答案分享出來(lái)的打算瘾英。
首先我們來(lái)看看extern的定義:
這是維基百科上的定義枣接,extern修飾的關(guān)鍵字,具有文件外部鏈接缺谴,但是聲明extern變量時(shí)但惶,編譯器并不會(huì)給這個(gè)變量分配內(nèi)存,在另外的文件中定義這個(gè)文件時(shí)才會(huì)為其分配內(nèi)存瓣赂,一旦聲明了extern關(guān)鍵字榆骚,對(duì)編譯器來(lái)意味著:
- 這個(gè)變量聲明(即數(shù)據(jù)類型和變量名,但是編譯器并沒(méi)有分配內(nèi)存)
- 這個(gè)變量的定義在其他文件中(在定義變量的文件中編譯器才會(huì)為其分配內(nèi)存)
這看上去很奇怪煌集,但是仔細(xì)想一想妓肢,這和函數(shù)的前置聲明以及類的前置聲明有異曲同工之處,在我看來(lái)這是為了將聲明與實(shí)現(xiàn)分離苫纤,便于文件之間的數(shù)據(jù)共享碉钠。
下面來(lái)看看extern的用法:
extern主要是為了解決在幾個(gè)源文件共享同一個(gè)變量,在鏈接各個(gè)cpp文件時(shí)卷拘。當(dāng)一個(gè)cpp文件在編譯的過(guò)程中喊废,若需要一個(gè)變量但是當(dāng)前的作用域沒(méi)有發(fā)現(xiàn)其定義,如果這個(gè)變量是extern修飾的栗弟,那么編譯器會(huì)知道其定義在其他文件中污筷,在obj文件的鏈接過(guò)程中會(huì)得到該變量的值。
![Uploading QQ截圖20160415194053_267714.jpg . . .]
如果我們僅僅在頭文件中聲明了extern變量而為初始化它乍赫,那么會(huì)出現(xiàn)” undefined reference to ‘global_x’ ”的錯(cuò)誤瓣蛀,在使用extern的關(guān)鍵字的時(shí)候要注意一下幾點(diǎn):
- extern變量可以聲明多次陆蟆,但是只能初始化一次,如下
-
extern變量的初始化需要在全局作用域中初始化惋增,所以在局部作用域中不論是聲明并初始化叠殷,或者聲明與初始化分開(kāi)都會(huì)導(dǎo)致編譯器報(bào)錯(cuò),如下:
一旦聲明了extern變量诈皿,那么在程序鏈接的時(shí)候無(wú)論它初始化沒(méi)有林束,都會(huì)查找extern的定義,如下:
這以上是extern的一些用法稽亏,我寫代碼的時(shí)候很少用到extern關(guān)鍵字壶冒,值得注意一點(diǎn)的是C語(yǔ)言中的函數(shù)原型是本身都具有外部鏈接的屬性的,在C語(yǔ)言中extern關(guān)鍵字的存在改變了變量的鏈接屬性措左,用extern關(guān)鍵字修飾的變量其定義將在別處依痊,編譯器的變量的解析將推遲到鏈接上,在實(shí)際中怎披,對(duì)于函數(shù)來(lái)說(shuō)extern將是沒(méi)有必要的修飾胸嘁,而在對(duì)變量的修飾中,最好將extern變量的聲明放在頭文件中凉逛,將變量的定義放在一個(gè)源文件中性宏。
相關(guān)資料:
extern的定義(Wiki需要科學(xué)上網(wǎng))
關(guān)于如何正確上網(wǎng)使用extern(本文主要參考這個(gè)回答)
如何組織extern頭文件和源文件(答主寫的很用心,值得一看状飞,我只看懂了一部分毫胜,捂臉。诬辈。酵使。。)
Keep focus and have fun!