天天看點

C++學習之路-内聯函數inline的使用一、定義-definition二、inline内聯函數使用舉例-example三、不建議使用内聯函數的情形四、宏定義函數(#define function …)五、宏定義函數與内聯函數的差別六、不相關學習tips

C++學習-内聯inline函數

  • 一、定義-definition
  • 二、inline内聯函數使用舉例-example
  • 三、不建議使用内聯函數的情形
    • 1.為什麼函數體代碼過多不建議使用inline函數
  • 四、宏定義函數(#define function ...)
  • 五、宏定義函數與内聯函數的差別
  • 六、不相關學習tips

一、定義-definition

使用inline修飾函數的聲明或者實作,就可以使其變成内聯函數。C++中支援内聯函數,其目的是為了提高函數的執行效率。

具體的作用就是:将函數調用,替換成函數體代碼,避免了調用函數時開辟棧空間和回收棧空間所帶來的記憶體開銷

二、inline内聯函數使用舉例-example

  • 被inline修飾的函數叫做内聯函數,内聯函數調用時,不會開辟棧空間,而是直接把函數體代碼拷貝過來。函數體積增大了,但是執行效率變高了。
//内聯函數的定義
inline void fuction()
{
	cout << "fuction" << endl;
	cout << "fuction" << endl;
	cout << "fuction" << endl;
	cout << "fuction" << endl;
}

int main(int argc, char **argv)
{
	//由于此函數為内聯函數,則沒有調用函數這回事,
	//也就是直接把函數調用,替換成函數體的代碼,放在這裡
	fuction();
	//其實這塊代碼就是cout << "fuction" << endl;
	//				 cout << "fuction" << endl;
	//				 cout << "fuction" << endl;
	//				 cout << "fuction" << endl;

	getchar();
	return 0;
}
           

三、不建議使用内聯函數的情形

  • 函數為遞歸函數,即是用inline修飾,也不會變成内聯函數
因為内聯是把函數調用轉為函數體代碼,而遞歸函數裡又存在函數調用,是以就循環了,導緻inline不起作用
//這個函數就是遞歸函數,即使用inline修飾,也不會變成内聯函數
inline void run()
{
	run();
}

int main(int argc, char **argv)
{
	//由于此函數為遞歸函數,即使被inline修飾,也會當做普通函數來看待
	run();

	getchar();
	return 0;
}
           
  • 函數體代碼較多,超過10行以上,不建議使用inline内聯函數
内聯函數會增加代碼的體積,因為直接把函數體放在了main函數裡。如果函數體數量很多,就會使得main函數中的代碼量劇增,這是我們不想看到的。

1.為什麼函數體代碼過多不建議使用inline函數

函數體積大時,就是函數體代碼過多,如果使用内聯函數,會增加機器碼的體積,也就會使得生成的exe檔案更大。由于函數調用不可能隻調用一次,是以函數體的代碼量是翻倍增長的。

四、宏定義函數(#define function …)

  • 宏定義不是函數,但是使用起來像函數。預處理器用複制宏代碼的方式代替函數的調用,省去了函數壓棧退棧過程,提高了效率。
//宏定義函數
#define add(v1,v2) ((v1)+(v2))

int main()
{
	add(1,2);//3

	getchar();
	return 0;
}
           

五、宏定義函數與内聯函數的差別

  • 内聯函數和宏都可以減少函數調用的開銷;
  • 對比宏定義,内聯函數多了文法檢測和函數特性,起碼看起來還是個函數;
  • 宏一個比較重要的特性就是,它隻是簡單的文本替換,不會檢測運算符的優先級之類的;
  • 宏定義函數是不可以調試的,而内聯函數是可以調試的;
  • 對于C++而言,宏定義一個最大的缺點就是無法操作類内的私有成員

六、不相關學習tips

  • Debug模式下不會産生任何内聯操作,隻有release模式才有内聯這回事
  • 函數調用時,首先開辟棧空間,調用結束時,會回收棧空間,整個過程有記憶體的開銷
  • C++的表達式是可以被指派的,但C語言是不可以的
(a > b ? a : b)表達式的意思是:
	if a>b return a;  
	else return b;
           

繼續閱讀