C++ 基礎 003 inline內聯函數話題

inline內聯函數話題

/*
 *運行平臺:Visual Studio 2015
 *參考資料:《C++ Primer Plus(第6版)》,傳智掃地增C++基礎課程
*/


一、前言

在講inline內聯函數之前,先問大家一個
  問題C++中的const常量可以在一定程度上替代宏常數定義,那麼是否有解決方案替代宏代碼片段呢?
  回答:肯定有的,畢竟C++是對C的升級嘛,C++中推薦使用內聯函數替代宏代碼片段

二:那麼怎麼使用呢?

   在C++中使用inline關鍵字聲明內聯函數,聲明時inline關鍵字必須和函數定義結合在一起否則編譯器會直接忽略內聯請求。如:inline void get();

三、注意

1、內聯函數生成的代碼中是沒有定義的

  C++編譯器直接將函數體插入在函數調用的地方 ,內聯函數沒有普通函數調用時的額外開銷(壓棧,跳轉,返回)。
  因此,當函數體的執行開銷遠大於壓棧,跳轉和返回所用的開銷時,那麼內聯將無意義。

inline void get()
{
	printf("Hello\n");
} 
int main()
{
	get();
	/* 相當於 */
	{
		printf("Hello\n");
	}
}

2、C++編譯器不一定準許函數的內聯請求

  內聯函數是一種特殊的函數,具有普通函數的特徵(參數檢查,返回類型等)。內聯函數是對編譯器的一種請求,既然是請求,那麼肯定可以拒絕,因此編譯器可能拒絕這種請求

3、inline與宏代碼片段區別

  內聯函數編譯器處理,直接將編譯後的函數體插入調用的地方。
  宏代碼片段預處理器處理, 進行簡單的文本替換有任何編譯過程

4、C++編譯器能夠進行編譯優化

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

5、C++中內聯編譯的限制

  • 能存在任何形式的循環語句
  • 能存在過多的條件判斷語句
  • 函數體過於龐大
  • 能對函數進行取址操作
  • 函數內聯聲明必須在調用語句之前

6、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); 
	printf("a = %d\n", a); 
	printf("b = %d\n", b);
	printf("c = %d\n", c);
	
	c = MYFUNC(++a, b);  
	printf("a = %d\n", a); 
	printf("b = %d\n", b);
	printf("c = %d\n", c);

	system("pause");
	return 0;
}

結果:可以看到兩者執行的結果不一致,因此使用#define定義代碼塊時可能會造成一定的副作用。
在這裏插入圖片描述
解釋:
在這裏插入圖片描述

結論:

  1. 內聯函數在編譯時直接將函數體插入函數調用的地方。
  2. inline只是一種請求,編譯器不一定允許這種請求。
  3. 內聯函數省去了普通函數調用時壓棧,跳轉和返回的開銷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章