1. 程式人生 > >行內函數與巨集函式的區別

行內函數與巨集函式的區別

行內函數

概念

以inline修飾的函式叫做行內函數,編譯時C++編譯器會在呼叫行內函數的地方展開,沒有函式壓棧的開銷,行內函數提升程式執行的效率

特性

  1. inline是一種以空間換時間的做法,省去呼叫函式額開銷。所以程式碼很長或者有迴圈/遞迴的的函式不適宜使用內聯
    2.inline對於編譯器而言只是一個建議,編譯器會自動優化,如果定義為inline的函式體內有迴圈/遞迴等等,編譯器優化時會忽略掉內聯
    3.inline必須函式定義放在一起,才能成為行內函數,僅將inline放在宣告前是不起作用的
    4.定義在類內的成員函式預設定義為行內函數

注意事項

在C++中,強制建議使用const代替巨集常量,使用行內函數代替巨集函式,const和行內函數在進行編譯時不僅進行替換,而且還會進行引數型別檢測,提高了程式的安全性。內斂函式可以是普通函式,也可以是類的成員函式;函式式巨集不能作為類的成員函式.

巨集

巨集函式與普通函式對比

優點:巨集函式在預處理期間會進行巨集替換,沒有函式壓棧開銷,執行效率高。
缺點:

1.不安全(不會進行型別檢測)
2.程式碼複用率不高
3.不停的進行替換,增長程式碼長度
4.不能除錯

巨集和行內函數的區別

1.行內函數採用的是值傳遞,而巨集定義採用的是對等替換.
2.巨集是由前處理器對巨集進行替代,而行內函數是通過編譯器控制來實現的。而且行內函數是真正的函式,只是在需要用到的時候,行內函數像巨集一樣的展開,所以取消了函式的引數壓棧,減少了呼叫的開銷
3.編譯器在呼叫一個行內函數時,會首先檢查它的引數的型別,保證呼叫正確。然後進行一系列的相關檢查,就像對待任何一個真正的函式一樣。這樣就消除了它的隱患和侷限性。

相關連結

注意事項:
1.在行內函數內不允許用迴圈語句和開關語句和遞迴。
2.行內函數的定義必須出現在行內函數第一次被呼叫之前。

define與const的區別

a.用#define MAX 255定義的常量是沒有型別的,所給出的是一個立即數,編譯器只是把所定義的常量值與所定義的常量的名字聯絡起來,define所定義的巨集變數在預處理的時候進行替換,在程式中使用到該常量的地方都要進行拷貝替換;
b.用const float MAX = 255; 定義的常量有型別名字,存放在記憶體的靜態區域中,在程式執行過程中const變數只有一個拷貝,而#define 所定義的巨集變數卻有多個拷貝,所以巨集定義在程式執行過程中所消耗的記憶體要比const變數的大得多;
c.用define定義的常量是不可以用指標變數去指向的,用const定義的常量是可以用指標去指向該常量的地址的;
d.用define可以定義一些簡單的函式,const是不可以定義函式的.

具體來說,有以下幾方面的區別:
1.編譯器處理方式
define – 在預處理階段進行替換
const – 在編譯時確定其值
2.型別檢查
define – 無型別,不進行型別安全檢查,可能會產生意想不到的錯誤
const – 有資料型別,編譯時會進行型別檢查
3.記憶體空間
define – 不分配記憶體,給出的是立即數,有多少次使用就進行多少次替換,在記憶體中會有多個拷貝,消耗記憶體大
const – 在靜態儲存區中分配空間,在程式執行過程中記憶體中只有一個拷貝
4.其他

a.在編譯時, 編譯器通常不為const常量分配儲存空間,而是將它們儲存在符號表中,這使得它成為一個編譯期間的常量,沒有了儲存與讀記憶體的操作,使得它的效率也很高。
b.巨集替換隻作替換,不做計算,不做表示式求解。
c.巨集定義的作用範圍僅限於當前檔案。
d.預設狀態下,const物件只在檔案內有效,當多個檔案中出現了同名的const變數時,等同於在不同檔案中分別定義了獨立的變數。 如果想在多個檔案之間共享const物件,必須在變數定義之前新增extern關鍵字(在宣告和定義時都要)。