含引數的巨集與函式的區別
巨集替換不佔執行時間,只佔編譯時間;而函式呼叫則佔執行時間(分配單元、保留現場、值傳遞、返回),所以每次執行都要載入所以執行起來比較慢一些。。
定義巨集的時候不要在巨集及其引數之間鍵入空格,因為巨集替換的時候會把你不經意打的空格當作巨集的一部分進去。
在巨集定義中把每個引數都用括號括起來,同時把整個結果也用括號(對於單個表示式的巨集,可以使用小括號(),對於巨集定義的復合語句可以使用{},linux核心中有乙個比較好的巨集定義,do while(0))括起來,以防止當巨集用於乙個更大的表示式時可能出現的問題。
使用巨集次數多時,巨集展開後源程式長,因為每展開一次都使程式增長,但是執行起來比較快一點(這也不是絕對的,當有很多巨集展開,目標檔案很大,執行的時候執行時系統換頁頻繁,效率就會低下)。而函式呼叫不使源程式變長。
函式呼叫時,先求出實參表示式的值,然後帶入形參。而使用帶參的巨集只是進行簡單的字元替換。
函式呼叫是在程式執行時處理的,分配臨時的記憶體單元;而巨集展開則是在編譯時進行的,在展開時並不分配記憶體單元,不進行值的傳遞處理,也沒有「返回值」的概念。
對函式中的實參和形參都要定義型別,二者的型別要求一致,如不一致,應進行型別轉換;而巨集不存在型別問題,巨集名無型別,它的引數也無型別,只是乙個符號代表,展開時帶入指定的字元即可。巨集定義時,字串可以是任何型別的資料。
呼叫函式只可得到乙個返回值,且有返回型別,而巨集沒有返回值和返回型別,但是用巨集可以設法得到幾個結果。
函式體內有bug,可以在函式體內打斷點除錯。如果巨集體內有bug,那麼在執行的時候是不能對巨集除錯的,即不能深入到巨集內部。
c++中巨集不能訪問物件的私有成員,但是成員函式就可以。
內聯函式和巨集的區別(內聯函式的優點)
內聯函式和巨集的區別在於,巨集是由預處理器對巨集進行替代,而內聯函式是通過編譯器控制來實現的。而且內聯函式是真正的函式,只是在需要用到的時候,內聯函式像巨集一樣的展開,所以取消了函式的引數壓棧,減少了呼叫的開銷。你可以象呼叫函式一樣來呼叫內聯函式,而不必擔心會產生於處理巨集的一些問題。
我們可以用inline來定義內聯函式,不過,任何在類的說明部分定義的函式都會被自動的認為是內聯函式。(當然內聯函式的識別對編譯器來說是乙個複雜的工作,後繼可能有專門的論述)
當然,內聯函式也有一定的侷限性。就是函式中的執行**不能太多了,如果,內聯函式的函式體過大,一般的編譯器會放棄內聯方式,而採用普通的方式呼叫函式。這樣,內聯函式就和普通函式執行效率一樣了。
內聯函式通過避免被呼叫的開銷來提高執行效率,尤其是它能夠通過呼叫(「過程化整合」)被編譯器優化。
如何選擇使用巨集還是函式:以下情況可以選擇巨集,其他情況最好選用函式
一般來說,用巨集來代表簡短的表示式比較合適。
在考慮效率的時候,可以考慮使用巨集,或者內聯函式。
在標頭檔案保護(防止重複包含編譯),條件編譯中的#ifdef,#if defined以及assert的實現
含引數的巨集與函式有什麼區別?
含引數的巨集有時完成的是函式實現的功能,但是並非所有的函式都可以被含引數的巨集所替代,各自特點如下 函式呼叫時,首先求出實參表示式的值,然後帶入形參。而使用帶參的巨集只是進行簡單的字元替換。函式呼叫是在程式執行時處理的,它需要分配臨時的記憶體單元 而巨集展開是在編譯時進行的,在展開時並不分配記憶體單...
論述含引數的巨集與函式的優缺點
1.函式呼叫時,先求出實參表示式的值,然後帶入形參。而使用帶參的巨集只是進行簡單的字元替換。2.函式呼叫是在程式執行時處理的,分配臨時的記憶體單元 而巨集展開則是在編譯時進行的,在展開時並不分配記憶體單元,不進行值的傳遞處理,也沒有 返回值 的概念。3.對函式中的實參和形參都要定義型別,二者的型別要...
帶引數的巨集與函式的區別
1.函式呼叫時,先求出實參表示式的值,然後帶入形參。而使用帶參的巨集只是進行簡單的字元替換。2.函式呼叫是在程式執行時處理的,分配臨時的記憶體單元 而巨集展開則是在編譯時進行的,在展開時並不分配記憶體單元,不進行值的傳遞處理,也沒有 返回值 的概念。3.對函式中的實參和形參都要定義型別,二者的型別要...