C++內聯函數詳情

內聯函數是C++當中為瞭提高程序運行效率的設計,老實講我沒有在其他語言當中看到類似的設計。它和常規函數之間的主要區別不在於編寫的方式,而是在於C++編譯器會將內聯函數組合到程序當中執行。

要解釋這個過程會稍稍有些復雜,我們需要從編譯的過程說起。對於編譯型語言而言,編譯器做的事情是把人類寫出來人能讀懂的代碼翻譯成機器能夠識別、執行的機器語言,一般是一串十六進制的指令。隨後計算機逐步執行這些指令,完成我們想要的功能。

當我們調用函數時,其實本質上是指令跳轉,先記錄下當前運行的指令位置,跳轉到函數所在的指令位置進行執行,執行完成之後再跳轉回來。這個當中除瞭跳轉之外,還會發生一些參數的傳遞和拷貝,需要一定的開銷。

而使用內聯函數,本質上可以理解成使用相應的函數代碼代替瞭函數調用。可以簡單理解成把函數當中的代碼拷貝瞭一份粘貼到瞭函數調用的位置,代替瞭函數跳轉。舉個例子,比如說我們有一個函數來計算坐標到原點的距離:

include<cmath>

double distance(double x, double y) {
    return sqrt(x * x + y * y);
}

double x = 3.0, y = 4.0;
double d = distance(x, y);

當我們使用瞭內聯函數之後,它相當於把函數的代碼拷貝瞭一份粘貼到瞭調用的位置:

double x = 3.0, y = 4.0;
double d = sqrt(x * x + y * y);

這也就是內聯的含義,使用瞭內聯函數之後,程序無須跳轉到另外一個位置進行執行,可以節省掉跳轉所帶來的開銷。因此運行效率要比普通函數更快,但代價是需要占用更多的內存。比如我們調用瞭10次內聯函數,相當於代碼拷貝瞭十份。

內聯函數的使用非常簡單,就是在函數定義之前加上inline關鍵字。

需要註意的是,有的時候我們雖然加上瞭inline關鍵字但編譯器並不一定會遵照執行。有些編譯器會有函數規模的限制,並且會限制內聯函數禁止調用自己,也就是不能遞歸。

還有一點是內聯函數雖然有內聯機制,但是函數的傳參依然是值傳遞,也就是說會發生拷貝,和普通函數一致。

在C語言當中沒有inline特性,C語言是使用宏定義來實現類似的功能。但宏定義並不是通過參數傳遞,而是代替機械替換實現的。

比如:

#define SQUARE(x) x*x

double a = SQUARE(3.4 + 3.5);

這樣我們得到的結果會是3.4 + 3.5 * 3.4 + 3.5,也就是說宏定義隻是機械地替換代碼,並不是函數式的調用。所以要實現類似inline函數的效果,可以使用括號:

#define SQUARE(x) ((x) * (x))

到此這篇關於C++內聯函數詳情的文章就介紹到這瞭,更多相關C++內聯函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

出品 | 公眾號:Coder梁(ID:Coder_LT)

推薦閱讀: