宏條件編譯和內聯函數inline

一、帶參宏和帶參函數的區別(宏定義的缺陷)
(1)宏定義是在預處理期間處理的,而函數是在編譯期間處理的。這個區別帶來的實質差異是:宏定義最終是在調用宏的地方把宏體原地展開,而函數是在調用函數處跳轉到函數中去執行,執行完後再跳轉回來。
注:宏定義和函數的最大差別就是:宏定義是原地展開,因此沒有調用開銷;而函數是跳轉執行再返回,因此函數有比較大的調用開銷。所以宏定義和函數相比,優勢就是沒有調用開銷,沒有傳參開銷,所以當函數體很短(尤其是隻有一句話時)可以用宏定義來替代,這樣效率高。
(2)帶參宏和帶參函數的一個重要差別就是:宏定義不會檢查參數的類型,返回值也不會附帶類型;而函數有明確的參數類型和返回值類型。當我們調用函數時編譯器會幫我們做參數的靜態類型檢查,如果編譯器發現我們實際傳參和參數聲明不同時會報警告或錯誤。
注:用函數的時候程序員不太用操心類型不匹配因爲編譯器會檢查,如果不匹配編譯器會提示;用宏的時候程序員必須很注意實際傳參和宏所希望的參數類型一致,否則可能編譯不報錯但是運行有誤
總結:宏和函數各有千秋,各有優劣。總的來說,如果代碼比較多用函數適合而且不影響效率;但是對於那些只有一兩句話的函數開銷就太大了,適合用帶參宏。但是用帶參宏又有缺點:不檢查參數類型。

二、內聯函數和inline關鍵字
(1)內聯函數通過在函數定義前加inline關鍵字實現。
(2)內聯函數本質上是函數,所以有函數的優點(內聯函數是編譯器負責處理的,編譯器可以幫我們做參數的靜態類型檢查);但是他同時也有帶參宏的優點(不用調用開銷,而是原地展開)。所以幾乎可以這樣認爲:內聯函數就是帶了參數靜態類型檢查的宏。
(3)當我們的函數內函數體很短(譬如只有一兩句話)的時候,我們又希望利用編譯器的參數類型檢查來排錯,我還希望沒有調用開銷時,最適合使用內聯函數。

三、宏定義來實現條件編譯(#define #undef #ifdef)
程序有DEBUG版本和RELEASE版本,區別就是編譯時有無定義DEBUG宏。
#include
#define SECOND_YEAR (365*24*60*60*60*2UL)//隨意定義一個數3784320000 (int範圍爲2的32次方(4字節),42開頭的十位數) (UL意爲轉化爲無符號數)
//條件編譯
#define DEBUG //調試模式
//#undef  DEBUG //取消定義這個DEBUG宏

#ifdef DEBUG
#define debug(x) printf(x)
#else
#define debug(x)
#endif

int main ()
{
int L= SECOND_YEAR;
printf("L = %u \n",L);  //這個無符號數沒有超出int範圍,正確顯示正數3784320000
debug("This is a debug mode\n");
}


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