日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言 内联函数

發布時間:2024/1/23 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言 内联函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【注:本文只討論C語言中的內聯函數,暫不談論C++,因為C++中這塊知識相對要更復雜。】

什么是內聯函數

在C語言中,如果一些函數被頻繁調用,不斷地有函數入棧,即函數棧,會造成棧空間或棧內存的大量消耗。
為了解決這個問題,特別的引入了inline修飾符,表示為內聯函數。
內聯函數是代碼被插入到調用者代碼處的函數。內聯函數通過避免被調用的開銷來提高執行效率

采用內聯函數實質是以空間換時間的做法

舉例:

void myprintf(int a) {printf(%d”,a); }int main() {for(i=0;i<100;i++myprintf(i); }

對于這個函數,在進行反復的打印i的過程中我們是不是要反復的調用myprintf()這個函數,進函數和出函數是需要時間的(入棧出棧),假設這個過程用時為4ms,而執行printf這個操作只需要2ms,那么在100次循環的過程中進出函數的時間比函數功能printf需要的時間還要長,這樣很影響工作效率。于是,我們就想要如何避免進出函數的過程呢?可以聲明inline這個關鍵字。

inline void myprintf(int a) {printf(%d”,a); }int main() {for(i=0;i<100;i++myprintf(i); }

main函數中的myprintf(i);會直接替換成該函數主體,上面的代碼在編譯時實際上是這樣的:

inline void myprintf(int a) {printf(%d”,a); }int main() {for(i=0;i<100;i++{printf(%d”,i);} }

內聯函數和宏定義區別

內聯函數看上去和宏定義非常相似。
對于上面的例子,我們可以用宏定義實現:

#define MYPRINTF(a) printf(“%d”,a);int main() {for(i=0;i<100;i++MYPRINTF(i); }

效果可以說與前面使用內聯的方式沒多大差別。
但宏定義在某些情況下會有問題,比如:

// 返回 i 的絕對值的宏 #define abs1(i) \( (i) >= 0 ? (i) : -(i) )// 返回 i 的絕對值的內聯函數 inline int abs2(int i) {return i >= 0 ? i : -i; }int fun();void userCode(int x) {int ans;ans = abs1(x++); // 錯誤!x 被增加兩次ans = abs1(fun()); // 錯誤!fun()被調用兩次ans = abs2(x++); // 正確! x 被增加一次ans = abs2(fun()); // 正確! fun() 被調用一次 }

ans = abs1(x++); 展開是ans = ( (x++) >= 0 ? (x++) : -(x++) );
所以x++會執行2次,這可能是用戶所不希望的。

內聯函數,與直接的函數調用區別僅在于沒有函數調用過程的消耗。保留了函數調用的特性,又提高函數的執行效率。

和宏不同的,還有內聯函數的參數類型被檢查,并且被正確地進行必要的類型轉換。

使用內聯函數注意事項

1、inline只適合函數體內代碼量少的函數使用,因為每一處內聯函數的調用都要復制代碼,如果該函數代碼量較大,將使程序的總代碼量增大,消耗更多的內存空間。

2、內聯函數本身不能是直接遞歸函數(自己內部還調用自己的函數)。因為這樣會在編譯時無窮無盡地展開。

3、如果執行函數體內代碼的時間,相比于函數調用的時間開銷較大,那么使用內聯的效率的收獲會很少。比如函數內有循環,這種情況就不考慮用內聯函數了。

4、關鍵字inline 必須與函數定義體放在一起才能使函數成為內聯,僅將inline 放在函數聲明前面不起任何作用。

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

5、對于功能復雜,內容較多的函數,即使加上inline修飾符,也不一定能作為內聯函數,因為編譯器會判定做優化。

關于static inline

static inline的內聯函數,一般情況下不會產生函數本身的代碼,而是全部被嵌入在被調用的地方。如果不加static,則表示該函數有可能會被其他編譯單元所調用,所以一定會產生函數本身的代碼。所以加了static,一般可令可執行文件變小。—【存疑,不確定】

static inline的內聯函數,只能在本文件內調用,而沒有static則可以被其他文件調用,這與static的常用方法一致。

函數的地址被使用的時候。如通過函數指針對函數進行了間接調用。這種情況下就不得不為static inline函數生成獨立的匯編碼,否則它沒有自己的地址。

參考鳴謝:

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

總結

以上是生活随笔為你收集整理的C语言 内联函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。