內聯函數和宏定義函數的區別

1、不同點:

  • 內聯函數是在編譯時展開,而宏在預編譯時展開;在編譯的時候,內聯函數直接被嵌入到目標代碼中去,而宏只是一個簡單的文本替換。
  • 內聯函數可以進行諸如類型安全檢查、語句是否正確等編譯功能,宏不具有這樣的功能;宏不是函數,而inline是函數。
  • 宏在定義時要小心處理宏參數,一般用括號括起來,否則容易出現二義性。而內聯函數不會出現二義性。
  • inline有點類似於宏定義,但是它和宏定義不同的是,宏定義只是簡單的文本替換,是在預編譯階段進行的。而inline的引入正是爲了取消這種複雜的宏定義的。

2、舉例:

  • 宏定義:
#define MAX(a,b) ((a)>(b)?(a):(b))
MAX(a,"Hello"); //錯誤地比較int和字符串,沒有參數類型檢查
  • 內聯函數:
#include <stdio.h>
 
inline int add(int a, int b)
{
    return (a + b);
}

int main(void)
{
    int a;

    a = add(1, 2);
    printf("a+b=%d\n", a);

    return 0;
}
以上a = add(1, 2);處在編譯時將被展開爲:
a = (a + b);

3、使用時的一些注意事項:

  • 使用宏定義一定要注意錯誤情況的出現,比如宏定義函數沒有類型檢查,可能傳進來任意類型,從而帶來錯誤,如舉例。還有就是括號的使用,宏在定義時要小心處理宏參數,一般用括號括起來,否則容易出現二義性
  • inline函數一般用於比較小的,頻繁調用的函數,這樣可以減少函數調用帶來的開銷。只需要在函數返回類型前加上關鍵字inline,即可將函數指定爲inline函數。
  • 同其它函數不同的是,最好將inline函數定義在頭文件,而不僅僅是聲明,因爲編譯器在處理inline函數時,需要在調用點內聯展開該函數,所以僅需要函數聲明是不夠的。

4、內聯函數使用的條件:

  • 內聯是以代碼膨脹(複製)爲代價,僅僅省去了函數調用的開銷,從而提高函數的執行效率。如果執行函數體內代碼的時間,相比於函數調用的開銷較大,那麼效率 的收穫會很少。另一方面,每一處內聯函數的調用都要複製代碼,將使程序的總代碼量增大,消耗更多的內存空間。以下情況不宜使用內聯: 
  • (1)如果函數體內的代碼比較長,使用內聯將導致內存消耗代價較高。 
  • (2)如果函數體內出現循環,那麼執行函數體內代碼的時間要比函數調用的開銷大。 
  • 內聯不是什麼時候都能展開的,一個好的編譯器將會根據函數的定義體,自動地取消不符合要求的內聯。

5、使用內聯函數和宏函數可能帶來的問題(慎用):

  • 有時不要僅是爲了提高編程效率而使用這兩種函數,要綜合考慮後再使用,因爲有時使用這兩種函數可能帶來其他的問題,比如出現問題不能使用gdb調試問題,內聯函數不展開,宏函數沒有參數檢測等

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章