第6課-行內函數分析
阿新 • • 發佈:2018-12-12
一、常量與巨集回顧
C++中的const
常量可以替代巨集常數定義,如:
const int A = 3; // #define A 3
二、行內函數
- C++中推薦使用行內函數替代巨集程式碼片段
- C++中使用
inline
關鍵字宣告行內函數
inline int func(int a,int b){
return a < b? a : b;
}
行內函數宣告時inline
關鍵字必須和函式定義結合在一起,否則編譯器會直接忽略內聯請求
- C++編譯器可以將一個函式進行內聯編譯
- 被C++編譯器內聯編譯的函式叫做行內函數
- C++編譯器直接將函式體插入函式呼叫的地方
- 行內函數沒有普通函式呼叫時的額外開銷(壓棧,跳轉,返回)
C++編譯器不一定滿足函式的內聯請求!
程式設計實驗:行內函數初探
#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);
printf("b = %d\n", b);
printf("c = %d\n", c);
return 0;
}
列印結果:
3
3
3
務必理解巨集定義的效果,是在使用位置直接替換。
- 行內函數具有普通函式的特徵(引數檢查,返回型別等)
- 函式的內聯請求可能被編譯器拒絕
- 函式被內聯編譯後,函式體直接擴充套件到呼叫的地方
巨集程式碼片段由前處理器處理,進行簡單的文字替換,沒有任何編譯過程,因此可能出現副作用
- 現代C++編譯器能夠進行編譯優化,一些函式即使沒有
inline
宣告,也可能被內聯編譯 - 一些現代C++編譯器提供了擴充套件語法,能夠對函式進行強制內聯,如:
- g++:
__attribute__((always_line))
屬性 - MSVC:
_forceinline
- g++:
程式設計實驗:行內函數深度示例
#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;
}
列印結果:r = 45
注意事項:
C++中inline
內聯編譯的限制:
- 不能存在任何形式的迴圈語句
- 不能存在過多的條件判斷語句
- 函式體不能過於龐大
- 不能對函式進行取址操作
- 函式內聯宣告必須在呼叫語句之前
三、總結
- C++中可以通過
inline
宣告行內函數 - 編譯器直接將行內函數體擴充套件到函式呼叫的地方
inline
只是一種請求,編譯器不一定允許這種請求- 行內函數省去了函式呼叫時壓棧,跳轉和返回的開銷