• 正文
  • 推薦器件
  • 相關(guān)推薦
申請入駐 產(chǎn)業(yè)圖譜

【C語言】內(nèi)聯(lián)函數(shù)總結(jié)

2024/02/19
2818
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

內(nèi)聯(lián)函數(shù)定義

inline關(guān)鍵字是C99標(biāo)準(zhǔn)的型關(guān)鍵字,其作用是將函數(shù)展開,把函數(shù)的代碼復(fù)制到每一個(gè)調(diào)用處。這樣調(diào)用函數(shù)的過程就可以直接執(zhí)行函數(shù)代碼,而不發(fā)生跳轉(zhuǎn)、壓棧等一般性函數(shù)操作??梢怨?jié)省時(shí)間,也會(huì)提高程序的執(zhí)行速度。

為什么需要內(nèi)聯(lián)函數(shù)

在C語言中,如果一些函數(shù)被頻繁的調(diào)用,不斷地用函數(shù)入棧,即函數(shù)棧,則會(huì)造成棧空間或者棧內(nèi)存的大量消耗,為了解決這個(gè)問題,特別的引入了inline關(guān)鍵字,表示為內(nèi)聯(lián)函數(shù)。

??臻g指的是函數(shù)內(nèi)數(shù)據(jù)的內(nèi)存空間,在一個(gè)系統(tǒng)下,??臻g的資源是有限的,假如頻繁大量的使用就會(huì)因??臻g的不足而導(dǎo)致出錯(cuò),函數(shù)的死循壞遞歸調(diào)用的最終結(jié)果就是導(dǎo)致棧內(nèi)存空間的枯竭。

#include?<stdio.h>
//函數(shù)定義為inline即:內(nèi)聯(lián)函數(shù)
inline?char*?dbtest(int?a)?{
????return?(i?%?2?>?0)???"奇"?:?"偶";
}?
?
int?main()
{
???int?i?=?0;
???for?(i=1;?i?<?100;?i++)?{
???????printf("i:%d????奇偶性:%s?/n",?i,?dbtest(i));????
???}
}

上面的例子就是標(biāo)準(zhǔn)的內(nèi)聯(lián)函數(shù)的用法,使用inline修飾帶來的好處我們表面看不出來,其實(shí),在內(nèi)部的工作就是在每個(gè)for循環(huán)的內(nèi)部任何調(diào)用dbtest(i)的地方都換成了(i % 2 > 0) ? "奇" : "偶",這樣就避免了頻繁調(diào)用函數(shù)對棧內(nèi)存重復(fù)開辟所帶來的消耗。

內(nèi)聯(lián)函數(shù)注意事項(xiàng)

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

如下風(fēng)格的函數(shù)fun則成為內(nèi)聯(lián)函數(shù):

void?fun(int?x,?int?y);
inline?void?fun(int?x,?int?y)??//inline與函數(shù)的定義放在一起
{

}
    關(guān)鍵字inline的使用是有所限制的

inline只適合函數(shù)體內(nèi)代碼比較簡單的函數(shù)使用,不能包含復(fù)雜的結(jié)構(gòu)控制語句,例如while、switch,并且內(nèi)聯(lián)函數(shù)本身不能是直接遞歸函數(shù)(函數(shù)內(nèi)部調(diào)用自己的函數(shù))。

    inline僅是一個(gè)對編譯器的建議

inline函數(shù)僅僅是一個(gè)對編譯器的建議,所以最后能否真正內(nèi)聯(lián),看編譯器的意思,它如果認(rèn)為函數(shù)不復(fù)雜,能在調(diào)用點(diǎn)展開,就會(huì)真正內(nèi)聯(lián),并不是說聲明了內(nèi)聯(lián)就會(huì)內(nèi)聯(lián),聲明內(nèi)聯(lián)只是一個(gè)建議而已。

    建議:inline函數(shù)的定義放在頭文件中

其次,因?yàn)閮?nèi)聯(lián)函數(shù)要在調(diào)用點(diǎn)展開,所以編譯器必須隨處可見內(nèi)聯(lián)函數(shù)的定義,要不然就成了非內(nèi)聯(lián)函數(shù)的調(diào)用了。所以,這要求每個(gè)調(diào)用了內(nèi)聯(lián)函數(shù)的文件都出現(xiàn)了該內(nèi)聯(lián)函數(shù)的定義

因此,將內(nèi)聯(lián)函數(shù)的定義放在頭文件里實(shí)現(xiàn)是合適的,省卻你為每個(gè)文件實(shí)現(xiàn)一次的麻煩。

聲明跟定義要一致:如果在每個(gè)文件里都實(shí)現(xiàn)一次該內(nèi)聯(lián)函數(shù)的話,那么,最好保證每個(gè)定義都是一樣的,否則,將會(huì)引起未定義的行為。如果不是每個(gè)文件里的定義都一樣,那么,編譯器展開的是哪一個(gè),那要看具體的編譯器而定。所以,最好將內(nèi)聯(lián)函數(shù)定義放在頭文件中。

    static和inline聯(lián)合使用

static是靜態(tài)修飾符,由其關(guān)鍵字修飾的變量會(huì)保存到全局?jǐn)?shù)據(jù)區(qū),對于普通的局部變量或者全局變量,都是由系統(tǒng)自動(dòng)分配內(nèi)存的,并且當(dāng)變量離開作用域的時(shí)候釋放掉,而使用static關(guān)鍵字來修飾,只有當(dāng)程序結(jié)束時(shí)候才會(huì)釋放掉,使用static inline修飾時(shí),函數(shù)僅在文件內(nèi)部可見,不會(huì)污染命名空間,另外,函數(shù)在運(yùn)行過程中也會(huì)分配內(nèi)存空間,但是由于static的存在,就和修飾變量類似,它只會(huì)開辟一塊內(nèi)存空間。

內(nèi)聯(lián)函數(shù)優(yōu)缺點(diǎn)

普通函數(shù)在調(diào)用過程中,會(huì)對寄存器中內(nèi)容進(jìn)行上下文切換(push和pop操作),而內(nèi)聯(lián)函數(shù)則不需要,所以普通函數(shù)相比內(nèi)聯(lián)函數(shù),耗時(shí)要多一些。

當(dāng)函數(shù)使用次數(shù)比較多的時(shí)候,內(nèi)聯(lián)函數(shù)在每個(gè)調(diào)用的地方都會(huì)被展開,所以導(dǎo)致固件大小會(huì)變大,同一段代碼會(huì)多次重復(fù)出現(xiàn)在固件中。而普通函數(shù)則沒有此問題,不管調(diào)用的函數(shù)的次數(shù)多少,函數(shù)在固件中均只占用一處,空間利用率較高。inline函數(shù)其實(shí)就是空間換時(shí)間

inline 和宏的區(qū)別

雖然inline函數(shù)和帶參數(shù)的宏很像,但是在使用方法上和宏還是有很大區(qū)別的:

inline()函數(shù) 帶參數(shù)的宏
展開的時(shí)機(jī) 在編譯的時(shí)候展開,因此inline關(guān)鍵字是一個(gè)編譯關(guān)鍵字 在預(yù)處理時(shí)展開,因此#define關(guān)鍵字是一個(gè)預(yù)處理關(guān)鍵字
參數(shù)類型檢查 inline()函數(shù)是一中函數(shù),會(huì)進(jìn)行嚴(yán)格的參數(shù)類型檢查 不會(huì)檢查參數(shù)類型,只是做簡單的字符串替換,因此在使用帶參數(shù)的宏時(shí)會(huì)有一些副作用,編寫程序是要人為預(yù)防
是否允許有復(fù)雜語句 不允許出現(xiàn)復(fù)雜語句,如果出現(xiàn)復(fù)雜語句,該函數(shù)將不會(huì)展開,例如遞歸,大型循環(huán)等 對此不做要求。宏只是做字符串替換操作,而不了解語句的含義
是否一定被展開 不一定,是否展開由編譯器決定 一定,只要使用了宏就可以保證被展開
接口封裝
是否支持調(diào)試

總結(jié)

內(nèi)聯(lián)函數(shù)相比宏函數(shù),會(huì)進(jìn)行語法檢查。宏函數(shù)是在預(yù)處理階段生效,內(nèi)聯(lián)函數(shù)是在編譯階段進(jìn)行語法檢查然后替換。

內(nèi)聯(lián)函數(shù)相比普通函數(shù),少了上下文切換的步驟所以執(zhí)行會(huì)更快一些。

內(nèi)聯(lián)函數(shù)被多次調(diào)用,會(huì)使固件大小膨脹,內(nèi)聯(lián)函數(shù)的高速是以空間來換時(shí)間。

內(nèi)聯(lián)函數(shù)不可遞歸。

如果函數(shù)內(nèi)容太過于復(fù)雜,編譯器會(huì)忽略inline關(guān)鍵字,把他當(dāng)成普通函數(shù)來處理。

本文參考

https://zhuanlan.zhihu.com/p/448262183

https://zhuanlan.zhihu.com/p/50812510

https://cloud.tencent.com/developer/article/2224955

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
MO-9200AE-D3E-HE87M3515420 1 Microchip Technology Inc LVDS Output Clock Oscillator, 87.351542MHz Nom
暫無數(shù)據(jù) 查看
CB3-3C-4M0000 1 CTS Corporation HCMOS/TTL Output Clock Oscillator, 4MHz Nom, GREEN, CERAMIC PACKAGE-4

ECAD模型

下載ECAD模型
$1.45 查看
ECS-.327-12.5-1210-TR 1 ECS International Inc Parallel - Fundamental Quartz Crystal, 0.032768MHz Nom, SMD, 2 PIN

ECAD模型

下載ECAD模型
$1.09 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶資源
  • 寫文章/發(fā)需求
立即登錄

作者就職于某500強(qiáng)公司,擔(dān)任BSP工程師。具有豐富的嵌入式開發(fā)經(jīng)驗(yàn)。專欄主要分享計(jì)算機(jī)基礎(chǔ),操作系統(tǒng),Linux驅(qū)動(dòng)開發(fā),Arm體系與架構(gòu),C/C++,數(shù)據(jù)結(jié)構(gòu)與算法等相關(guān)文章。歡迎關(guān)注我的公眾號(hào)【嵌入式與Linux那些事】,一起學(xué)習(xí)交流。