乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      extern C的作用詳解

       細(xì)寒 2014-07-28

           extern "C"的主要作用就是為了能夠正確實(shí)現(xiàn)C++代碼調(diào)用其他C語(yǔ)言代碼。加上extern "C"后,會(huì)指示編譯器這部分代碼按C語(yǔ)言的進(jìn)行編譯,而不是C++的。由于C++支持函數(shù)重載,因此編譯器編譯函數(shù)的過程中會(huì)將函數(shù)的參數(shù)類型也加到編譯后的代碼中,而不僅僅是函數(shù)名;而C語(yǔ)言并不支持函數(shù)重載,因此編譯C語(yǔ)言代碼的函數(shù)時(shí)不會(huì)帶上函數(shù)的參數(shù)類型,一般之包括函數(shù)名。

           這個(gè)功能十分有用處,因?yàn)樵贑++出現(xiàn)以前,很多代碼都是C語(yǔ)言寫的,而且很底層的庫(kù)也是C語(yǔ)言寫的,為了更好的支持原來(lái)的C代碼和已經(jīng)寫好的C語(yǔ)言庫(kù),需要在C++中盡可能的支持C,而extern "C"就是其中的一個(gè)策略。

      這個(gè)功能主要用在下面的情況:

      1、C++代碼調(diào)用C語(yǔ)言代碼

      2、在C++的頭文件中使用

      3、在多個(gè)人協(xié)同開發(fā)時(shí),可能有的人比較擅長(zhǎng)C語(yǔ)言,而有的人擅長(zhǎng)C++,這樣的情況下也會(huì)有用到

      給出一個(gè)我設(shè)計(jì)的例子:

      moduleA、moduleB兩個(gè)模塊,B調(diào)用A中的代碼,其中A是用C語(yǔ)言實(shí)現(xiàn)的,而B是利用C++實(shí)現(xiàn)的,下面給出一種實(shí)現(xiàn)方法:

      //moduleA頭文件

      #ifndef __MODULE_A_H //對(duì)于模塊A來(lái)說,這個(gè)宏是為了防止頭文件的重復(fù)引用

      #define __MODULE_A_H

      int fun(int, int);

      #endif

      //moduleA實(shí)現(xiàn)文件moduleA.C //模塊A的實(shí)現(xiàn)部分并沒有改變

      #include"moduleA"

      int fun(int a, int b)

      {

      return a+b;

      }

      //moduleB頭文件

      #idndef __MODULE_B_H //很明顯這一部分也是為了防止重復(fù)引用

      #define __MODULE_B_H

      #ifdef __cplusplus //而這一部分就是告訴編譯器,如果定義了__cplusplus(即如果是cpp文件, extern "C"{ //因?yàn)閏pp文件默認(rèn)定義了該宏),則采用C語(yǔ)言方式進(jìn)行編譯

      #include"moduleA.h"

      #endif

      … //其他代碼

      #ifdef __cplusplus

      }

      #endif

      #endif

      //moduleB實(shí)現(xiàn)文件 moduleB.cpp //B模塊的實(shí)現(xiàn)也沒有改變,只是頭文件的設(shè)計(jì)變化了

      #include"moduleB.h"

      int main()

      {

      cout<<fun(2,3)<<endl;

      }

      下面是詳細(xì)的介紹:

      由于C、C++編譯器對(duì)函數(shù)的編譯處理是不完全相同的,尤其對(duì)于C++來(lái)說,支持函數(shù)的重載,編譯后的函數(shù)一般是以函數(shù)名和形參類型來(lái)命名的。

      例如函數(shù)void fun(int, int),編譯后的可能是(不同編譯器結(jié)果不同)_fun_int_int(不同編譯器可能不同,但都采用了類似的機(jī)制,用函數(shù)名和參數(shù)類型來(lái)命名編譯后的函數(shù)名);而C語(yǔ)言沒有類似的重載機(jī)制,一般是利用函數(shù)名來(lái)指明編譯后的函數(shù)名的,對(duì)應(yīng)上面的函數(shù)可能會(huì)是_fun這樣的名字。

      看下面的一個(gè)面試題:為什么標(biāo)準(zhǔn)頭文件都有類似的結(jié)構(gòu)?

      #ifndef __INCvxWorksh /*防止該頭文件被重復(fù)引用*/

      #define __INCvxWorksh

      #ifdef __cplusplus             //告訴編譯器,這部分代碼按C語(yǔ)言的格式進(jìn)行編譯,而不是C++的

      extern "C"{

      #endif

      /*…*/

      #ifdef __cplusplus

      }

      #endif

      #endif /*end of __INCvxWorksh*/

      分析:

      • 顯然,頭文件中編譯宏"#ifndef __INCvxWorksh 、#define __INCvxWorksh、#endif"(即上面代碼中的藍(lán)色部分)的作用是為了防止該頭文件被重復(fù)引用
      • 那么

      #ifdef __cplusplus (其中__cplusplus是cpp中自定義的一個(gè)宏?。?!)

      extern "C"{

      #endif

      #ifdef __cplusplus

      }

      #endif

      的作用是什么呢?

      extern "C"包含雙重含義,從字面上可以知道,首先,被它修飾的目標(biāo)是"extern"的;其次,被它修飾的目標(biāo)代碼是"C"的。

      • 被extern "C"限定的函數(shù)或變量是extern類型的

      extern是C/C++語(yǔ)言中表明函數(shù)和全局變量的作用范圍的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其申明的函數(shù)和變量可以在本模塊或其他模塊中使用。

      記住,下面的語(yǔ)句:

      extern int a; 僅僅是一個(gè)變量的聲明,其并不是在定義變量a,并未為a分配空間。變量a在所有模塊中作為一種全局變量只能被定義一次,否則會(huì)出錯(cuò)。

      通常來(lái)說,在模塊的頭文件中對(duì)本模塊提供給其他模塊引用的函數(shù)和全局變量以關(guān)鍵字extern生命。例如,如果模塊B要引用模塊A中定義的全局變量和函數(shù)時(shí)只需包含模塊A的頭文件即可。這樣模塊B中調(diào)用模塊A中的函數(shù)時(shí),在編譯階段,模塊B雖然找不到該函數(shù),但并不會(huì)報(bào)錯(cuò);它會(huì)在鏈接階段從模塊A編譯生成的目標(biāo)代碼中找到該函數(shù)。

      extern對(duì)應(yīng)的關(guān)鍵字是static,static表明變量或者函數(shù)只能在本模塊中使用,因此,被static修飾的變量或者函數(shù)不可能被extern C修飾。

      • 被extern "C"修飾的變量和函數(shù)是按照C語(yǔ)言方式進(jìn)行編譯和鏈接的:這點(diǎn)很重要?。。?!

      上面也提到過,由于C++支持函數(shù)重載,而C語(yǔ)言不支持,因此函數(shù)被C++編譯后在符號(hào)庫(kù)中的名字是與C語(yǔ)言不同的;C++編譯后的函數(shù)需要加上參數(shù)的類型才能唯一標(biāo)定重載后的函數(shù),而加上extern "C"后,是為了向編譯器指明這段代碼按照C語(yǔ)言的方式進(jìn)行編譯

      未加extern "C"聲明時(shí)的鏈接方式:

      //模塊A頭文件 moduleA.h

      #idndef _MODULE_A_H

      #define _MODULE_A_H

      int foo(int x, int y);

      #endif

      在模塊B中調(diào)用該函數(shù):

      //模塊B實(shí)現(xiàn)文件 moduleB.cpp

      #include"moduleA.h"

      foo(2,3);

      實(shí)際上,在鏈接階段,連接器會(huì)從模塊A生成的目標(biāo)文件moduleA.obj中找_foo_int_int這樣的符號(hào)?。?!,顯然這是不可能找到的,因?yàn)閒oo()函數(shù)被編譯成了_foo的符號(hào),因此會(huì)出現(xiàn)鏈接錯(cuò)誤。

      常見的做法可以參考下面的一個(gè)實(shí)現(xiàn):

      moduleA、moduleB兩個(gè)模塊,B調(diào)用A中的代碼,其中A是用C語(yǔ)言實(shí)現(xiàn)的,而B是利用C++實(shí)現(xiàn)的,下面給出一種實(shí)現(xiàn)方法:

      //moduleA頭文件

      #ifndef __MODULE_A_H //對(duì)于模塊A來(lái)說,這個(gè)宏是為了防止頭文件的重復(fù)引用

      #define __MODULE_A_H

      int fun(int, int);

      #endif

      //moduleA實(shí)現(xiàn)文件moduleA.C //模塊A的實(shí)現(xiàn)部分并沒有改變

      #include"moduleA"

      int fun(int a, int b)

      {

      return a+b;

      }

      //moduleB頭文件

      #idndef __MODULE_B_H //很明顯這一部分也是為了防止重復(fù)引用

      #define __MODULE_B_H

      #ifdef __cplusplus //而這一部分就是告訴編譯器,如果定義了__cplusplus(即如果是cpp文件, extern "C"{ //因?yàn)閏pp文件默認(rèn)定義了該宏),則采用C語(yǔ)言方式進(jìn)行編譯

      #include"moduleA.h"

      #endif

      … //其他代碼

      #ifdef __cplusplus

      }

      #endif

      #endif

      //moduleB實(shí)現(xiàn)文件 moduleB.cpp //B模塊的實(shí)現(xiàn)也沒有改變,只是頭文件的設(shè)計(jì)變化了

      #include"moduleB.h"

      int main()

      {

      cout<<fun(2,3)<<endl;

      }

      extern "C"的使用要點(diǎn)

      1. 可以是單一語(yǔ)句

          extern "C" double sqrt(double);

      2. 可以是復(fù)合語(yǔ)句, 相當(dāng)于復(fù)合語(yǔ)句中的聲明都加了extern "C"

          extern "C"

         {

            double sqrt(double);

            int min(int, int);

        }

      3.可以包含頭文件,相當(dāng)于頭文件中的聲明都加了extern "C"

         extern "C"

        {

          #i nclude <cmath>

        }

      4. 不可以將extern "C" 添加在函數(shù)內(nèi)部

      5. 如果函數(shù)有多個(gè)聲明,可以都加extern "C", 也可以只出現(xiàn)在第一次聲明中,后面的聲明會(huì)接受第一個(gè)鏈接指示符的規(guī)則。

      6. 除extern "C", 還有extern "FORTRAN" 等。

      參考文章:

      extern C使用

      extern c的作用【轉(zhuǎn)】_看雪..

      extern C使用要點(diǎn)

      http://blog./u/29619/showart_230148.html

      http://blog.csdn.net/weiqubo/archive/2009/10/16/4681813.aspx

      http://hi.baidu.com/sundl2268/blog/item/4969453d2258bae53c6d970a.html

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多