一、什么是內聯函數
在C語言中,如果一些函數被頻繁的調用,不斷地用函數入棧,即函數棧,則會造成棧空間或者棧內存的大量消耗,為了解決這個問題,特別的引入了inline關鍵字,表示為內聯函數。棧空間指的是函數內數據的內存空間,在一個系統下,棧空間的資源是有限的,假如頻繁大量的使用就會因棧空間的不足而導致出錯,函數的死循壞遞歸調用的最終結果就是導致棧內存空間的枯竭。
像下面這個例子:
#include <stdio.h> //函數定義為內聯函數 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)); } return 0; }
此例子就是內聯函數的標准用法,使用內聯函數帶來的好處就是,在每個for循壞內部任何調用dbtest(i)的地方都將會替換成(i % 2 > 0 ? "奇" : "偶"),因此,通過這樣子的替換就可以避免了頻繁調用函數對棧內存重復開辟所帶來的消耗。
二、內聯函數的編程風格
1、關鍵字inline必須與函數的定義體放在一起,才能使函數成為內聯函數,僅僅將inline放在函數聲明前面不起作用
例如,下面風格的函數fun將不能成為內聯函數:
inline void fun(int x, int y); //inline僅僅與函數聲明放在一起 void fun(int x, int y) { }
如下風格的函數fun則成為內聯函數:
void fun(int x, int y); inline void fun(int x, int y) //inline與函數的定義放在一起 { }
2、關鍵字inline的使用是有所限制的
inline只適合函數體內代碼比較簡單的函數使用,不能包含復雜的結構控制語句,例如while、switch,並且內聯函數本身不能是直接遞歸函數(函數內部調用自己的函數)。
三、慎用內聯
內聯能提高函數的執行效率,但是不能把所有的函數都定義為內聯函數,內聯是以代碼膨脹(復制)為代價的,僅僅是省去了函數調用的開銷,從而提高函數的執行效率。如果執行函數體內代碼的時間,相比於函數調用的開銷較大,那么執行的效率收獲會很少,另一方面,每一處內聯函數的調用都會復制代碼,從而使程序的總代碼量增加,消耗更多的內存空間。
下面情況不適合使用內聯函數:
(1)如果函數體內的代碼較長,使用內聯將導致內存消耗代價較高;
(2)如果函數體內出現循壞,那么執行函數體內的代碼將要比函數調用的開銷更大。
四、static和inline聯合使用
static是靜態修飾符,由其關鍵字修飾的變量會保存到全局數據區,對於普通的局部變量或者全局變量,都是由系統自動分配內存的,並且當變量離開作用域的時候釋放掉,而使用static關鍵字來修飾,只有當程序結束時候才會釋放掉,使用static inline修飾時,函數僅在文件內部可見,不會污染命名空間,另外,函數在運行過程中也會分配內存空間,但是由於static的存在,就和修飾變量類似,它只會開辟一塊內存空間。
