日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C/C 语言中extern的用法

發布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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的用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。