国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

C++編程中隊(duì)內(nèi)聯(lián)函數(shù)的理解和使用

2020-05-23 14:09:57
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
這篇文章主要介紹了C++編程中隊(duì)內(nèi)聯(lián)函數(shù)的理解和使用,簡(jiǎn)單舉例講解了inline關(guān)鍵字引出的內(nèi)聯(lián)函數(shù)的相關(guān)知識(shí),需要的朋友可以參考下
 

函數(shù)調(diào)用過(guò)程
c++經(jīng)過(guò)編譯生成可執(zhí)行程序文件exe,存放在外存儲(chǔ)器中。程序啟動(dòng),系統(tǒng)從外存儲(chǔ)器中將可執(zhí)行文件裝載到內(nèi)存中,從入口地址(main函數(shù)起始處)開(kāi)始執(zhí)行。程序執(zhí)行中遇到了對(duì)其他函數(shù)的調(diào)用,就暫停當(dāng)前函數(shù)的執(zhí)行,并保存下一條指令的地址作為從被調(diào)函數(shù)返回后繼續(xù)執(zhí)行的入口點(diǎn),保存現(xiàn)場(chǎng)。然后轉(zhuǎn)到被調(diào)函數(shù)的入口地址執(zhí)行被調(diào)函數(shù)。遇到return語(yǔ)句或者被調(diào)函數(shù)結(jié)束后,恢復(fù)先前保存的現(xiàn)場(chǎng),從先前保存的返回地址處繼續(xù)執(zhí)行主調(diào)函數(shù)的其余部分。

內(nèi)聯(lián)函數(shù)
函數(shù)調(diào)用需要進(jìn)行現(xiàn)場(chǎng)保護(hù),以便在函數(shù)調(diào)用之后繼續(xù)進(jìn)行。函數(shù)調(diào)用后還需要恢復(fù)現(xiàn)場(chǎng)才能繼續(xù)執(zhí)行。這都需要系統(tǒng)開(kāi)銷,影響了程序的效率。

內(nèi)聯(lián)函數(shù)在編譯的時(shí)候?qū)⑺{(diào)用的函數(shù)代碼直接嵌入到主調(diào)函數(shù)中,定義方式就是在普通的函數(shù)定義前面加上inline,不存在程序流程跳轉(zhuǎn)和返回,但是增加了程序代碼。內(nèi)聯(lián)函數(shù)函數(shù)體不能含有復(fù)雜的結(jié)構(gòu)控制語(yǔ)句,適用于1-5行的小函數(shù)。當(dāng)函數(shù)規(guī)模比較大的時(shí)候,函數(shù)運(yùn)行的時(shí)間相對(duì)與函數(shù)的調(diào)用和返回時(shí)間大很多,綜合時(shí)間和空間考慮,用內(nèi)聯(lián)沒(méi)有太大意義。

原理:
對(duì)于任何內(nèi)聯(lián)函數(shù),編譯器在符號(hào)表里放入函數(shù)的聲明(包括名字、參數(shù)類型、返回值類型)。如果編譯器沒(méi)有發(fā)現(xiàn)內(nèi)聯(lián)函數(shù)存在錯(cuò)誤,那么該函數(shù)的代碼也被放入符號(hào)表里。在調(diào)用一個(gè)內(nèi)聯(lián)函數(shù)時(shí),編譯器首先檢查調(diào)用是否正確(進(jìn)行類型安全檢查,或者進(jìn)行自動(dòng)類型轉(zhuǎn)換,當(dāng)然對(duì)所有的函數(shù)都一樣)。如果正確,內(nèi)聯(lián)函數(shù)的代碼就會(huì)直接替換函數(shù)調(diào)用,于是省去了函數(shù)調(diào)用的開(kāi)銷。

內(nèi)聯(lián)函數(shù)與宏的區(qū)別
1.內(nèi)聯(lián)函數(shù)在運(yùn)行時(shí)可調(diào)試,而宏定義不可以;

2.編譯器會(huì)對(duì)內(nèi)聯(lián)函數(shù)的參數(shù)類型做安全檢查或自動(dòng)類型轉(zhuǎn)換(同普通函數(shù)),而宏定義則不會(huì);

3.內(nèi)聯(lián)函數(shù)可以訪問(wèn)類的成員變量,宏定義則不能;

4.在類中聲明同時(shí)定義的成員函數(shù),自動(dòng)轉(zhuǎn)化為內(nèi)聯(lián)函數(shù)。

 

C++ 語(yǔ)言的函數(shù)內(nèi)聯(lián)機(jī)制既具備宏代碼的效率,又增加了安全性,而且可以自由操作類的數(shù)據(jù)成員。所以在C++ 程序中,應(yīng)該用內(nèi)聯(lián)函數(shù)取代所有宏代碼

一個(gè)可執(zhí)行文件的cpp文件中一個(gè)函數(shù)只能被定義一次。如果你把函數(shù)定義在一個(gè).h文件中并讓兩個(gè)cpp包含就會(huì)造成這個(gè)函數(shù)分別在兩個(gè)cpp中被定義產(chǎn)生錯(cuò)誤。但是inline函數(shù)是允許在多個(gè)cpp中多次定義的,就解決了這個(gè)問(wèn)題。

for (int i=v.begin() ; i<v.size() ; i++) {   .... } 

       對(duì)于size()的調(diào)用,其實(shí)是內(nèi)聯(lián)。在循環(huán)時(shí),可以采用變量保存v.size()的值,以減少每個(gè)循環(huán)的調(diào)用開(kāi)支。于是決定一搜,順便總結(jié)之。

1、inline的引出

考慮下列min()函數(shù)

int min( int v1, int v2 ) {   return( v1 < v2 << v1 : v2 ); } 

      為這樣的小操作定義一個(gè)函數(shù)的好處是:
     a.如果一段代碼包含min()的調(diào)用,那閱讀這樣的代碼并解釋其含義比讀一個(gè)條件操作符的實(shí)例,可讀性會(huì)強(qiáng)很多。

     b.改變一個(gè)局部化的實(shí)現(xiàn)比更改一個(gè)應(yīng)用中的300個(gè)出現(xiàn)要容易得多

     c.語(yǔ)義是統(tǒng)一的,每個(gè)測(cè)試都能保證相同的方式實(shí)現(xiàn)

     d.函數(shù)可以被重用,不必為其他的應(yīng)用重寫(xiě)代碼

     不過(guò),將min()寫(xiě)成函數(shù)有一個(gè)嚴(yán)重的缺點(diǎn):調(diào)用函數(shù)比直接計(jì)算條件操作符要慢很多。那怎么能兼顧以上優(yōu)點(diǎn)和效率呢?C++提供的解決方案為inline(內(nèi)聯(lián))函數(shù)

2、inline的原理:代碼替代

       在程序編譯時(shí),編譯器將程序中出現(xiàn)的內(nèi)聯(lián)函數(shù)的調(diào)用表達(dá)式用內(nèi)聯(lián)函數(shù)的函數(shù)體來(lái)進(jìn)行替代。

       例如,如果一個(gè)函數(shù)被指定為inline 函數(shù)則它將在程序中每個(gè)調(diào)用點(diǎn)上被內(nèi)聯(lián)地展開(kāi)例如

int minVal2 = min( i, j ); 

在編譯時(shí)被展開(kāi)為

int minVal2 = i < j << i : j; 

 則把min()寫(xiě)成函數(shù)的額外執(zhí)行開(kāi)銷從而被消除了。
3、inline的使用

       讓一個(gè)函數(shù)成為內(nèi)聯(lián)函數(shù),隱式的為在類里定義函數(shù),顯式的則是在函數(shù)前加上inline關(guān)鍵字說(shuō)明。

4、使用inline的一些注意事項(xiàng)

      a.從inline的原理,我們可以看出,inline的原理,是用空間換取時(shí)間的做法,是以代碼膨脹(復(fù)制)為代價(jià),僅僅省去了函數(shù)調(diào)用的開(kāi)銷,從而提高函數(shù)的執(zhí)行效率。如果執(zhí)行函數(shù)體內(nèi)代碼的時(shí)間,相比于函數(shù)調(diào)用的開(kāi)銷較大,那么效率的收獲會(huì)很少。所以,如果函數(shù)體代碼過(guò)長(zhǎng)或者函數(shù)體重有循環(huán)語(yǔ)句,if語(yǔ)句或switch語(yǔ)句或遞歸時(shí),不宜用內(nèi)聯(lián)

      b.關(guān)鍵字inline 必須與函數(shù)定義體放在一起才能使函數(shù)成為內(nèi)聯(lián),僅將inline 放在函數(shù)聲明前面不起任何作用。內(nèi)聯(lián)函數(shù)調(diào)用前必須聲明。

inline void Foo(int x, int y); // inline 僅與函數(shù)聲明放在一起 void Foo(int x, int y) {   ... } 

以上代碼不能成為內(nèi)聯(lián)函數(shù),而以下則可以

void Foo(int x, int y); inline void Foo(int x, int y) // inline 與函數(shù)定義體放在一起 {   ... } 

       所以說(shuō),inline 是一種“用于實(shí)現(xiàn)的關(guān)鍵字”,而不是一種“用于聲明的關(guān)鍵字”。對(duì)于以上例子,林銳還建議,只在定義前加上inline,而不是在聲明和定義前都加,因?yàn)檫@能體現(xiàn)高質(zhì)量C++/C 程序設(shè)計(jì)風(fēng)格的一個(gè)基本原則:聲明與定義不可混為一談。
       c.inline對(duì)于編譯器來(lái)說(shuō)只是一個(gè)建議,編譯器可以選擇忽略該建議。換句話說(shuō),哪怕真的寫(xiě)成了inline,也沒(méi)有任何錯(cuò)誤的情況下,編譯器會(huì)自動(dòng)進(jìn)行優(yōu)化。所以當(dāng)inline中出現(xiàn)了遞歸,循環(huán),或過(guò)多代碼時(shí),編譯器自動(dòng)無(wú)視inline聲明,同樣作為普通函數(shù)調(diào)用。


總結(jié)下:

       覺(jué)得可以將內(nèi)聯(lián)理解為C++中對(duì)于函數(shù)專有的宏,對(duì)于C的函數(shù)宏的一種改進(jìn)。對(duì)于常量宏,C++提供const替代;而對(duì)于函數(shù)宏,C++提供的方案則是inline。在C中,大家都知道宏的優(yōu)勢(shì),編譯器通過(guò)復(fù)制宏代碼的方式,省去了參數(shù)壓棧,生成匯編的call調(diào)用,返回參數(shù)等操作,雖然存在一些安全隱患,但在效率上,還是很可取的。
       不過(guò)函數(shù)宏還是有不少缺陷的,主要有以下:

       a.在復(fù)制代碼時(shí),容易出現(xiàn)一想不到的邊際效應(yīng),比如經(jīng)典的

#define MAX(a, b) (a) > (b) ? (a) : (b) 

在執(zhí)行語(yǔ)句:

result = MAX(i, j) + 2 ; 

時(shí),會(huì)被解釋為

result = (i) > (j) ? (i) : (j) + 2 ; 

     b.使用宏,無(wú)法進(jìn)行調(diào)試,雖然windows提供了ASSERT宏
     c.使用宏,無(wú)法訪問(wèn)類的私有成員
      所以,C++ 通過(guò)內(nèi)聯(lián)機(jī)制,既具備宏代碼的效率,又增加了安全性,還可以自由操作類的數(shù)據(jù)成員,算是一個(gè)比較完美的解決方案。



發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 海林市| 霍州市| 芒康县| 涞源县| 沁阳市| 磴口县| 丽江市| 乐陵市| 定日县| 密山市| 宜丰县| 阿克苏市| 曲靖市| 民乐县| 罗平县| 嵊泗县| 怀化市| 东乌珠穆沁旗| 新巴尔虎右旗| 丹阳市| 聂拉木县| 永福县| 鸡泽县| 岫岩| 临西县| 固镇县| 菏泽市| 丹江口市| 乌鲁木齐市| 乌兰察布市| 兴文县| 黑河市| 沧源| 施甸县| 威海市| 崇文区| 邓州市| 临武县| 府谷县| 佛冈县| 芦山县|