1. 程式人生 > >C++筆記 第六課 行內函數分析---狄泰學院

C++筆記 第六課 行內函數分析---狄泰學院

如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。 學習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只是一種請求,編譯器不一定允許這種請求 行內函數省去了函式呼叫時壓棧,跳轉和返回的開銷