C/C 语言中extern的用法
聲明外部變量
????現代編譯器一般采用按文件編譯的方式,因此在編譯時,各個文件中定義的全局變量是互相透明的,也就是說,在編譯時,全局變量的可見域限制在文件內部。下面舉一個簡單的例子。創建一個工程,里面含有A.cpp和B.cpp兩個簡單的C 源文件:
//A.cpp int?i; void?main() { }//B.cpp int i;????這兩個文件極為簡單,在A.cpp中定義了一個全局變量i,在B中也定義了一個全局變量i。對A和B分別編譯,都可以正常通過編譯,但是進行鏈接的時候,卻出現了錯誤,錯誤提示如下:
linking... B.obj:errorLNK2005:?"int?i"?(?i@@?3HA?)?already?defined?in?A.obj Debug/A.exe:fatal?error?LNK1169:?one?or?more?multiply?defined?symbols?found Error?executing?link.exe. A.exe - 2 error(s), 0 warning(s)????這就是說,在編譯階段,各個文件中定義的全局變量相互是透明的,編譯A時覺察不到B中也定義了i,同樣,編譯B時覺察不到A中也定義了i。但是在鏈接階段,要將各個文件的內容“合為一體”,因此,如果某些文件中定義的全局變量名相同的話,在鏈接階段就會報重復定義(one?or?more?multiply?defined?symbols)的錯誤。
????因此,各個文件中定義的全局變量名不可相同。
????在鏈接階段,編譯產生的obj文件合并了A、B兩文件的內容,這也是出現int i重復定義錯誤的原因。
舉個例子
????一個文件中定義的全局變量,可以在整個程序的任何地方被使用,舉例說,如果A文件中定義了某全局變量,那么B文件中也可以使用該變量。修改我們的程序,加以驗證:
//A.cpp void?main() {i?=?100;? //試圖使用B中定義的全局變量 }//B.cpp int i;????出現如下意料之中的編譯錯誤,未定義int i錯誤(undeclared?identifier?Error),因為在鏈接之前A、B文件中的變量是彼此不可見的。
Compiling... A.cpp C:/Documents and Settings/wangjian/桌面/try extern/A.cpp(5) : error C2065: 'i' : undeclared identifier Error?executing?cl.exe. A.obj?-?1?error(s),?0?warning(s)????編譯器沒有能夠意識到,某個變量符號雖然不是本文件定義的,但是它可能是在其它的文件中定義的,為了避免錯誤的發生extern派上用場了。為上面的錯誤程序加上extern關鍵字后,順利通過編譯,鏈接,代碼如下:
//A.cpp extern?int?i; void?main() {??i?=?100;?//試圖使用B中定義的全局變量 }//B.cpp int i;在C 文件中調用C方式編譯的函數
????相對于C,C 中新增了諸如重載等新特性,它們的編譯有一些重要區別。將下面的小程序分別按C和C 方式編譯,來探討兩種編譯方式的區別。
int?i; int?func(int?t) {return?0; } void?main() { }????以C方式編譯的結果如下:
COMM? ?_i??:??DWORD PUBLIC? ?_func PUBLIC? ?_main????以C 方式編譯的結果如下:
PUBLIC? ?i@@?3HA? ? ?;?i PUBLIC? ?func@@YAHH@Z? ;?func PUBLIC? _main????可見,C方式編譯下,變量名和函數名之前被統一加上了一個下劃線,而C 編譯后的結果卻復雜的多,i變成了?i@@ 3HA ,func變成了?func@@YAHH@Z。C 中的這種看似復雜的命名規則是為C 中的函數重載,參數檢查等特性服務的。
不同編譯方式下的函數調用
????如果在工程中,不僅有CPP文件,還有以C方式編譯的C文件,函數調用就會有一些微妙之處。有如下CPP文件A.CPP和C文件B.C兩個文件。
//A.CPP void?func(); void?main() {func(); } //B.C void func() { }????對A.CPP和B.C分別編譯,都沒有問題,但是鏈接時出現錯誤,原因就是C和CPP不同的編譯方式產生的沖突。比如在上文中提到,C方式編譯下,變量名和函數名之前被統一加上了一個下劃線,而C 編譯后的結果卻復雜的多,i變成了?i@@ 3HA。
linking... A.obj?:?error?LNK2001:?unresolved?external?symbol?"void?__cdecl?func(void)"?(?func@@YAXXZ) Debug/A.exe?:?fatal?error?LNK1120:?1?unresolved?externals Error?executing?link.exe. A.exe - 2 error(s), 0 warning(s)????此時,可以通過extern關鍵字,來幫助編譯器解決上面提到的問題。對于本例,只需將A.CPP改成如下代碼即可:
//A.CPP extern "C" {void func(); //引入C語言方式編譯的函數或變量 } void main() {func(); }聲明:
本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。
總結
以上是生活随笔為你收集整理的C/C 语言中extern的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何解除手机bl锁(如何解除手机bl锁小
- 下一篇: C语言中return的各种用法