C语言 内联函数
【注:本文只討論C語言中的內(nèi)聯(lián)函數(shù),暫不談?wù)揅++,因?yàn)镃++中這塊知識(shí)相對(duì)要更復(fù)雜。】
什么是內(nèi)聯(lián)函數(shù)
在C語言中,如果一些函數(shù)被頻繁調(diào)用,不斷地有函數(shù)入棧,即函數(shù)棧,會(huì)造成棧空間或棧內(nèi)存的大量消耗。
為了解決這個(gè)問題,特別的引入了inline修飾符,表示為內(nèi)聯(lián)函數(shù)。
內(nèi)聯(lián)函數(shù)是代碼被插入到調(diào)用者代碼處的函數(shù)。內(nèi)聯(lián)函數(shù)通過避免被調(diào)用的開銷來提高執(zhí)行效率。
采用內(nèi)聯(lián)函數(shù)實(shí)質(zhì)是以空間換時(shí)間的做法
舉例:
void myprintf(int a) {printf(“%d”,a); }int main() {for(i=0;i<100;i++)myprintf(i); }對(duì)于這個(gè)函數(shù),在進(jìn)行反復(fù)的打印i的過程中我們是不是要反復(fù)的調(diào)用myprintf()這個(gè)函數(shù),進(jìn)函數(shù)和出函數(shù)是需要時(shí)間的(入棧出棧),假設(shè)這個(gè)過程用時(shí)為4ms,而執(zhí)行printf這個(gè)操作只需要2ms,那么在100次循環(huán)的過程中進(jìn)出函數(shù)的時(shí)間比函數(shù)功能printf需要的時(shí)間還要長(zhǎng),這樣很影響工作效率。于是,我們就想要如何避免進(jìn)出函數(shù)的過程呢?可以聲明inline這個(gè)關(guān)鍵字。
inline void myprintf(int a) {printf(“%d”,a); }int main() {for(i=0;i<100;i++)myprintf(i); }main函數(shù)中的myprintf(i);會(huì)直接替換成該函數(shù)主體,上面的代碼在編譯時(shí)實(shí)際上是這樣的:
inline void myprintf(int a) {printf(“%d”,a); }int main() {for(i=0;i<100;i++){printf(“%d”,i);} }內(nèi)聯(lián)函數(shù)和宏定義區(qū)別
內(nèi)聯(lián)函數(shù)看上去和宏定義非常相似。
對(duì)于上面的例子,我們可以用宏定義實(shí)現(xiàn):
效果可以說與前面使用內(nèi)聯(lián)的方式?jīng)]多大差別。
但宏定義在某些情況下會(huì)有問題,比如:
ans = abs1(x++); 展開是ans = ( (x++) >= 0 ? (x++) : -(x++) );
所以x++會(huì)執(zhí)行2次,這可能是用戶所不希望的。
而內(nèi)聯(lián)函數(shù),與直接的函數(shù)調(diào)用區(qū)別僅在于沒有函數(shù)調(diào)用過程的消耗。保留了函數(shù)調(diào)用的特性,又提高函數(shù)的執(zhí)行效率。
和宏不同的,還有內(nèi)聯(lián)函數(shù)的參數(shù)類型被檢查,并且被正確地進(jìn)行必要的類型轉(zhuǎn)換。
使用內(nèi)聯(lián)函數(shù)注意事項(xiàng)
1、inline只適合函數(shù)體內(nèi)代碼量少的函數(shù)使用,因?yàn)槊恳惶巸?nèi)聯(lián)函數(shù)的調(diào)用都要復(fù)制代碼,如果該函數(shù)代碼量較大,將使程序的總代碼量增大,消耗更多的內(nèi)存空間。
2、內(nèi)聯(lián)函數(shù)本身不能是直接遞歸函數(shù)(自己內(nèi)部還調(diào)用自己的函數(shù))。因?yàn)檫@樣會(huì)在編譯時(shí)無窮無盡地展開。
3、如果執(zhí)行函數(shù)體內(nèi)代碼的時(shí)間,相比于函數(shù)調(diào)用的時(shí)間開銷較大,那么使用內(nèi)聯(lián)的效率的收獲會(huì)很少。比如函數(shù)內(nèi)有循環(huán),這種情況就不考慮用內(nèi)聯(lián)函數(shù)了。
4、關(guān)鍵字inline 必須與函數(shù)定義體放在一起才能使函數(shù)成為內(nèi)聯(lián),僅將inline 放在函數(shù)聲明前面不起任何作用。
inline void Foo(int x, int y); // inline 僅與函數(shù)聲明放在一起 void Foo(int x, int y) { }5、對(duì)于功能復(fù)雜,內(nèi)容較多的函數(shù),即使加上inline修飾符,也不一定能作為內(nèi)聯(lián)函數(shù),因?yàn)榫幾g器會(huì)判定做優(yōu)化。
關(guān)于static inline
static inline的內(nèi)聯(lián)函數(shù),一般情況下不會(huì)產(chǎn)生函數(shù)本身的代碼,而是全部被嵌入在被調(diào)用的地方。如果不加static,則表示該函數(shù)有可能會(huì)被其他編譯單元所調(diào)用,所以一定會(huì)產(chǎn)生函數(shù)本身的代碼。所以加了static,一般可令可執(zhí)行文件變小。—【存疑,不確定】
static inline的內(nèi)聯(lián)函數(shù),只能在本文件內(nèi)調(diào)用,而沒有static則可以被其他文件調(diào)用,這與static的常用方法一致。
函數(shù)的地址被使用的時(shí)候。如通過函數(shù)指針對(duì)函數(shù)進(jìn)行了間接調(diào)用。這種情況下就不得不為static inline函數(shù)生成獨(dú)立的匯編碼,否則它沒有自己的地址。
參考鳴謝:
https://blog.csdn.net/zqixiao_09/article/details/50877383
https://www.cnblogs.com/linux-bfbdxj520/p/11405474.html
https://www.jb51.net/article/41520.htm
https://blog.csdn.net/chuqierliang/article/details/48053417
https://blog.csdn.net/weixin_33895657/article/details/92037511
https://blog.csdn.net/qq_33757398/article/details/81390151
https://blog.csdn.net/weixin_30706507/article/details/96192546
總結(jié)
- 上一篇: STM32 map文件解析
- 下一篇: C语言 void和void *(无类型指