1. 程式人生 > >c++——inline內聯函數

c++——inline內聯函數

pri pause 判斷語句 pau 直接 UNC order lsp 參數檢查

1 inline內聯函數

C++中的const常量可以替代宏常數定義,如:

const int A = 3; ? #define A 3

C++中是否有解決方案替代宏代碼片段呢?(替代宏代碼片段就可以避免宏的副作用!)

C++中推薦使用內聯函數替代宏代碼片段

C++中使用inline關鍵字聲明內聯函數

內聯函數聲明時inline關鍵字必須和函數定義結合在一起,否則編譯器會直接忽略內聯請求。

//宏替換和函數調用區別

#include "iostream"

using namespace std;

#define MYFUNC(a, b) ((a) < (b) ? (a) : (b))

inline int myfunc(int a, int b)

{

return a < b ? a : b;

}

int main()

{

int a = 1;

int b = 3;

//int c = myfunc(++a, b); //頭疼系統

int c = MYFUNC(++a, b);

printf("a = %d\n", a);

printf("b = %d\n", b);

printf("c = %d\n", c);

system("pause");

return 0;

}

說明1:

必須inline int myfunc(int a, int b)和函數體的實現,寫在一塊

說明2

C++編譯器可以將一個函數進行內聯編譯

被C++編譯器內聯編譯的函數叫做內聯函數

內聯函數在最終生成的代碼中是沒有定義的

C++編譯器直接將函數體插入在函數調用的地方 //內聯函數和宏定義類似,是函數體的替換

內聯函數沒有普通函數調用時的額外開銷(壓棧,跳轉,返回)

說明3:C++編譯器不一定準許函數的內聯請求!

說明4

內聯函數是一種特殊的函數,具有普通函數的特征(參數檢查,返回類型等)

內聯函數是對編譯器的一種請求,因此編譯器可能拒絕這種請求

內聯函數由 編譯器處理,直接將編譯後的函數體插入調用的地方

宏代碼片段 由預處理器處理, 進行簡單的文本替換,沒有任何編譯過程

說明5:

現代C++編譯器能夠進行編譯優化,因此一些函數即使沒有inline聲明,也可能被編譯器內聯編譯

另外,一些現代C++編譯器提供了擴展語法,能夠對函數進行強制內聯

如:g++中的__attribute__((always_inline))屬性

說明6:

C++中內聯編譯的限制:

不能存在任何形式的循環語句

不能存在過多的條件判斷語句

函數體不能過於龐大

不能對函數進行取址操作

函數內聯聲明必須在調用語句之前

編譯器對於內聯函數的限制並不是絕對的,內聯函數相對於普通函數的優勢只是省去了函數調用時壓棧,跳轉和返回的開銷。

因此,當函數體的執行開銷遠大於壓棧,跳轉和返回所用的開銷時,那麽內聯將無意義。

結論:
1)內聯函數在編譯時直接將函數體插入函數調用的地方

2)inline只是一種請求,編譯器不一定允許這種請求

3)內聯函數省去了普通函數調用時壓棧,跳轉和返回的開銷

c++——inline內聯函數