內(nèi)聯(lián)函數(shù)的作用
內(nèi)聯(lián)函數(shù)是一種編譯機制,優(yōu)點從代碼上是看不出來的,但是程序的執(zhí)行效率上有差別,通常,編譯器對函數(shù)調(diào)用的處理是一種類似中斷的方式,即當執(zhí)行到函數(shù)調(diào)用語句時,程序把當前所有的狀態(tài)信息比如CPU所有寄存器(其中一個很重要的就是指令指針寄存器)的值保存起來,然后放心大膽地轉(zhuǎn)去執(zhí)行那個函數(shù)的代碼,執(zhí)行完后再返回原來的地方,恢復(fù)原先保存過的狀態(tài)信息,于是也就可以接著原來被中斷的指令繼續(xù)往下執(zhí)行。
這樣,就很容易實現(xiàn)代碼的結(jié)構(gòu)化,因為可以把一些獨立的功能模塊寫成函數(shù),函數(shù)內(nèi)部的變量和外部的變量互不影響,而且函數(shù)執(zhí)行完后就可以釋放這個函數(shù)內(nèi)部變量的所使用的內(nèi)存空間(這就是為什么函數(shù)退出后,其內(nèi)部變量不再有效),對內(nèi)存的使用也是很經(jīng)濟的(否則,如果一個大的程序全部由一個函數(shù)組成,那么所有的變量都得自始至終地占用內(nèi)存空間),當然,還有其他優(yōu)點,比如可以實現(xiàn)遞歸,總之是好處多多。
可是,任何事情往往都有兩方面,這樣做雖然好處多多,但也是有代價的,那就是前面所說的,任何一次函數(shù)調(diào)用,程序都得進行保存和恢復(fù)狀態(tài)信息的動作,用數(shù)據(jù)結(jié)構(gòu)的術(shù)語說就是進棧和退棧,當然,還有內(nèi)存分配的過程,如果函數(shù)的代碼非常少,這種代價并不是可忽略的,比如說,你編寫一個類,里面有個記錄狀態(tài)的成員變量:
Class MyClass
{
private:
int m_iState;
}
按照面向?qū)ο蟮乃枷耄瘮?shù)的屬性應(yīng)盡量的私有化,但外部怎么獲得這個屬性值呢?一般的方法就是加一個共有函數(shù),這就實現(xiàn)的面向?qū)ο笏枷胫兴^“通過公用接口操作對象的私有屬性”。于是就變成了:
Class MyClass
{
public:
int GetState();
private:
int m_iState;
}
int MyClass::GetState()
{
return m_iState;
}
這樣一來,面向?qū)ο笏枷氲故求w現(xiàn)出來了,但你的CPU會恨你:“你丫一個鳥函數(shù)就返回一個整數(shù)卻讓老子進一次棧、彈一次棧”,內(nèi)存也會埋怨:“兄弟也得跟著分配內(nèi)存!”
但對你來說,也很委屈,怎么辦,把所有的屬性都改成public?讓外部內(nèi)碼直接訪問?況且,那樣也不解決所有問題,因為有時候即使不是為了面向?qū)ο螅覀円残枰血毩⒌墓δ苣K做成函數(shù),比如說產(chǎn)生隨機數(shù)的函數(shù)。我想
int iRand=rand();
總比:
int iRand=((int)(MULTIPLIER * Seed + INCREMENT)》》16)&0x7fff;
看起來舒服吧?(我這里只是打個比方,VC的rand函數(shù)并不是內(nèi)聯(lián)函數(shù))
而內(nèi)聯(lián)函數(shù)就是解決這個問題了,對于程序員,他還是把獨立功能寫成函數(shù)的形式,但只要聲明為內(nèi)聯(lián),編譯器就不把它編譯成一次函數(shù)調(diào)用,而只是類似于把函數(shù)的代碼拷貝到被調(diào)用的地方,而且這完全是編譯器私下里完成的,原來的訪問權(quán)限等問題絲毫不受影響。這不是兩全齊美了嗎:在保證代碼的面向?qū)ο笮院徒Y(jié)構(gòu)化不受損失的條件下,程序的效率也沒有損失,比如上面那個類,就變成了:
Class MyClass
{
public:
inline int GetState();
private:
int m_iState;
}
int inline MyClass::GetState()
{
return m_iState;
}
有一點要注意,內(nèi)聯(lián)函數(shù)要跟類的聲明寫在同一個文件中,否則編譯會出錯。按照VC管理源文件的風格來說,就是內(nèi)聯(lián)函數(shù)最好寫在聲明類的.h文件中,而不是像一般函數(shù)那樣寫在實現(xiàn)類的.cpp文件中。
當然,內(nèi)聯(lián)函數(shù)還有另外一種寫法,就是直接寫在類中,此時,不必使用“inline”關(guān)鍵字。
Class MyClass
{
public:
int GetState(){ return m_iState; }
private:
int m_iState;
}
最后,還要注意,內(nèi)聯(lián)函數(shù)只是一種編譯機制,用上面兩種形式聲明的函數(shù)僅僅是建議編譯器進行內(nèi)聯(lián),而編譯器是否內(nèi)聯(lián)不一定。正如前面所說,函數(shù)調(diào)用的開銷只是對小的函數(shù)不可忽略,對于重量級的函數(shù)還是可以忽略的,而且在絕大多數(shù)的場合,函數(shù)調(diào)用才是人間正道,才是解決問題的最佳。所以大多數(shù)編譯器并不把帶有循環(huán)、遞歸等或者代碼比較多的函數(shù)進行內(nèi)聯(lián)編譯,有的甚至不允許聲明成內(nèi)聯(lián)的。
C語言的內(nèi)聯(lián)函數(shù)的作用
[cpp] view plain copy關(guān)內(nèi)聯(lián)函數(shù)鍵字inline
[cpp] view plain copyvoid myprintf(int a)
{
priintf(“%d”,a);
}
int main()
{
for(i=0;i《100;i++)
myprintf(3);
}
對于這個函數(shù),在進行反復(fù)的打印3的過程中我們是不是要反復(fù)的調(diào)用myprintf(int a)這個函數(shù),進函數(shù)和出函數(shù)是需要時間的,假設(shè)這個過程用時為4ms,而執(zhí)行printf這個操作只需要2ms,那么在100次循環(huán)的過程中進出函數(shù)的時間比函數(shù)功能printf需要的時間還要長,這樣很影響工作效率。于是,我們就想要如何去免去進出函數(shù)的過程呢?那么就可以聲明inline這個關(guān)鍵字,有何用途?當我們聲明了一個inline的函數(shù)時候,函數(shù)被調(diào)用的語句就被替換成了函數(shù)本身,進行了一個預(yù)處理
[cpp] view plain copyint main()
{
for(i=0;i《100;i++)
void myprintf(3)
{
printf(“%d”,3);
}
return 0;
}
這樣一來我就非常明顯的知道這個函數(shù)是干什么的了,就不需要去調(diào)用函數(shù)的定義部分,再通俗點講,原來我要從家里去外面的商店去買冰淇淋(來回需要時間),現(xiàn)在商店就在我家里面了,那么我是不是省去了去商店的時間呢?但是相應(yīng)的我這個家要很大(也就是所謂的空間要很大才能包含這個商店對吧?)這樣就是用空間去換取了時間了。
內(nèi)聯(lián)函數(shù)在編譯層面類似于宏替換。也就是說,程序執(zhí)行過程中調(diào)用內(nèi)聯(lián)函數(shù)不需要入棧出棧,所以效率會提高。
[cpp] view plain copy#include《stdio.h》
inline int add(int x, int y)
{
return x+y;
}
int main()
{
int i,j,k;
printf(“請輸入兩個整數(shù)的值:”);
scanf(“%d%d”,&i,&j);
k=add(i,j);
printf(“k=%d\n”,k);
return 0;
}
-
C語言
+關(guān)注
關(guān)注
180文章
7614瀏覽量
137732 -
內(nèi)聯(lián)函數(shù)
+關(guān)注
關(guān)注
0文章
10瀏覽量
2251
原文標題:內(nèi)聯(lián)函數(shù)在C語言中的作用
文章出處:【微信號:mcuworld,微信公眾號:嵌入式資訊精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
EE-62:在C語言中訪問短字內(nèi)存
![EE-62:<b class='flag-5'>在</b><b class='flag-5'>C</b><b class='flag-5'>語言中</b>訪問短字內(nèi)存](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
EE-128:C語言中的DSP:從C調(diào)用匯編類成員函數(shù)
![EE-128:<b class='flag-5'>C</b><b class='flag-5'>語言中</b>的DSP:從<b class='flag-5'>C</b>調(diào)用匯編類成員<b class='flag-5'>函數(shù)</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
C語言中申請的堆內(nèi)存能不能自動釋放
C語言中的socket編程基礎(chǔ)
技術(shù)干貨驛站 ▏深入理解C語言:編程高手必備,全方位解析運算符的核心技能!
![技術(shù)干貨驛站 ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:編程高手必備,全方位<b class='flag-5'>解析</b>運算符的核心技能!](https://file1.elecfans.com/web2/M00/07/AD/wKgaombqh7SAbkiwAABRwFmh1fQ416.png)
C語言指針詳細解析
c語言中從左到右結(jié)合怎么看
卷積神經(jīng)網(wǎng)絡(luò)激活函數(shù)的作用
PHP用戶定義函數(shù)詳細講解
C語言數(shù)據(jù)類型有哪些
![<b class='flag-5'>C</b><b class='flag-5'>語言</b>數(shù)據(jù)類型有哪些](https://file1.elecfans.com/web2/M00/C5/16/wKgZomX6UKqAb6q4AABHS7gAoYk070.png)
淺談C語言中的函數(shù)定義
介紹C語言中錯誤處理和異常處理的一些常用的方法和策略
C語言中的可變參數(shù)介紹
![<b class='flag-5'>C</b><b class='flag-5'>語言中</b>的可變參數(shù)介紹](https://file1.elecfans.com/web2/M00/C2/BA/wKgaomXezG6AcBLhAABI4KQSKz0893.png)
評論