C++筆記 第六課 行內函數分析---狄泰學院
阿新 • • 發佈:2018-12-16
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。 學習C++編譯環境:Linux
第六課 行內函數分析
1.C++中的const常量可以替代巨集常數定義
如: const int A = 3; <–> #define A 3 C++中是否有解決方案替代巨集程式碼片段呢?有,行內函數
2.行內函數
C++中推薦使用行內函數替代巨集程式碼片段 C++中使用inline關鍵字宣告行內函數
inline int func(int a, int b)
{
return a< b ? a: b;
}
行內函數宣告時inline關鍵字必須和函式定義結合在一起,否則編譯器會直接忽略內聯請求。 C++編譯器可以將一個函式進行內聯編譯 被C++編譯器內聯編譯的函式叫做行內函數 C++編譯器直接將函式體插入函式呼叫的地方 行內函數沒有普通函式呼叫時的額外開銷(壓棧,跳轉,返回) C++編譯器不一定滿足函式的內聯請求
6-1 行內函數初探
#include <stdio.h> #define FUNC(a, b) ((a) < (b) ? (a) : (b)) inline int func(int a, int b) { return a < b ? a : b; } int main(int argc, char *argv[]) { int a = 1; int b = 3; int c = FUNC(++a, b); printf("a = %d\n", a); // 2 printf("b = %d\n", b); // 3 printf("c = %d\n", c); // 2 return 0; } 執行結果: int c = FUNC(++a, b); //巨集程式碼塊出現副作用 int c = ((++a) < (b) ? (++a) : (b)); //文字替換後 2<3?,是,返回++a,此時a= 3 a = 3 b = 3 c = 3 int c = func(++a, b); //函式呼叫 a = 2 b = 3 c = 2
行內函數具有普通函式的特徵(引數檢查,返回型別等) 函式的內聯請求可能被編譯器拒絕 函式被內聯編譯後,函式體直接擴充套件到呼叫的地方 巨集程式碼片段由前處理器處理,進行簡單的文字替換,沒有任何編譯過程,因此可能出現副作用。 現代C++編譯器能夠進行編譯優化,一些函式即使沒有inline宣告,也可能被內聯編譯 一些現代C++編譯器提供了擴充套件語法,能夠對函式進行強制內聯,如: g++:attribute((always_inline))屬性 MSVC:_forceinline
6-2 行內函數深度示例
#include <stdio.h> //__forceinline //__attribute__((always_inline)) inline int add_inline(int n); int main(int argc, char *argv[]) { int r = add_inline(10); printf(" r = %d\n", r); return 0; } inline int add_inline(int n) { int ret = 0; for(int i=0; i<n; i++) { ret += i; } return ret; }
3.注意事項
C++中inline內聯編譯的限制 不能存在任何形式的迴圈語句 不能存在過多的條件判斷語句 函式體不能過於龐大 不能對函式進行取值操作 函式內聯宣告必須在呼叫語句之前 小結 C++中可以通過inline宣告行內函數 編譯器直接將行內函數體擴充套件到函式呼叫的地方 inline只是一種請求,編譯器不一定允許這種請求 行內函數省去了函式呼叫時壓棧,跳轉和返回的開銷