C++學習記錄(四)——內聯

有關宏定義的缺陷

宏的缺陷:

1. 僅僅是作一個簡單的替換,編譯器並不知道宏定義這回事。
2. 宏定義的沒有做用域,須要手動卸載
3. 因爲C++中預處理器不能訪問雷內,因此宏定義不能成爲類內函數c++

舉一個簡單的例子:
#define SQUARE(X) X*X//定義一個計算平方的宏
這個並非經過傳參數來實現的,只是簡單的替換,因此:函數

a = SQUARE(5.0);
b = SQUARE(1.0 + 2.0);
c = SQUARE(c++);

結果就是:
a = 5.0*5.0
b = 1.0 + 2.0* 1.0 + 2.0
c = c++*c++
雖然,咱們能夠#define SQUARE(X) ((X)*(X))來解決,可是這裏仍然致命的問題:宏不能按值傳遞。即使使用新的定義,咱們仍然阻止不了c遞增了兩次。code

內聯(inline)

內聯函數和常規函數

二者在寫法上沒有區別。只需在常規函數的聲明前加 inline 關鍵字便可。
二者區別在於C++編譯器是如何將其組合到程序中的。從而也能理解爲何說內聯是爲了提高C++程序效率所作的一項改進。內存

常規函數的調用

在進行常規函數調用時會使程序跳到另外一個地址(函數地址),並在函數結束時返回。具體來講,執行到函數調用指令時,程序將函數調用後當即存儲該指令的內存地址,並將函數參數複製到堆棧,跳轉到編輯函數起點的內存單元,執行函數代碼(若是有返回值的話,將其放入寄存器中),而後跳回到地址被保存的指令處。在這樣反覆橫跳的同時必然形成了必定的開銷。作用域

內聯函數的調用

編譯器將使用相應的函數代碼替換函數調用。這樣程序無需跳到另外一處去執行代碼,而後在跳回來。雖然內聯函數的運行速度比常規函數快,可是消耗了更多內存。這時候咱們便存在取捨:編譯器

  • 若是執行代碼的時間比處理函數調用的時間長,則所節省的時間不過只佔整個過程的一小部分。
  • 若是代碼執行時間很短則內聯調用就能夠節省非內聯調用使用的絕大部分時間。(雖然節省了時間,可是時間的絕對值並不大)

因此,當你的函數內容短小,邏輯簡單並且常常被調用,那麼內聯絕對是很是好的選擇。編譯

內聯的使用

  • 函數聲明前加 inline 關鍵字
  • 函數定義前加 inline 關鍵字

須要注意的是,知足如下條件中的任意一條的函數,編譯器都不會作內聯處理。效率

  • 存在任何形式的循環語句
  • 存在過多的條件語句
  • 函數體過於龐大
  • 對函數進行取地址操做

咱們發現一個事情:上述的4個條件中出現了很含糊的詞語——「過於」。這使咱們不由想問,這個「過於龐大」,「過多」到底是一個什麼標準?循環

沒錯!程序

其實,內聯僅僅是給編譯器的一個建議,編譯器不必定接受你的建議。並且,就算你沒有聲明將函數聲明爲內聯函數,編譯器也可能作內聯處理。因此,這裏僅僅是單純的講述有內聯這麼一回事。~~~~

相關文章
相關標籤/搜索