C inline 內聯函式

2021-06-26 12:16:44 字數 2693 閱讀 1173

內聯函式:

(1)       內聯函式定義和作用:

將乙個函式宣告為inline,那麼函式就成為內聯函式。內聯函式通常就是它在程式中每個呼叫點上「內聯地」展開。從定義上看,內聯函式跟一般函式不一樣,一般函式呼叫的時候是需要呼叫開銷的(比如出棧入棧等操作),內聯函式從定義上看更像是巨集,但是跟巨集不一樣。

內聯函式的作用主要就是使用在一些短小而使用非常頻繁的函式中,為了減少函式呼叫的開銷,為了避免使用巨集(在c++中,巨集是不建議使用的)。比如內聯函式inline int  func(int x) 在呼叫的時候cout《編譯時將被展開為:

cout<<(x*x)<(2)       內聯函式相對於巨集的區別和優點:

從上面的分析中,可以看出,內聯函式在表現形式上與巨集很類似。但是內聯函式和巨集之間的區別很明顯。巨集是在預處理時進行的機械替換,內聯是在編譯時進行的。內聯函式是真正的函式,只是在呼叫時,沒有呼叫開銷,像巨集一樣進行展開。內聯函式會進行引數匹配檢查,相對於帶引數的巨集有很好的優點,避免了處理巨集的一些問題。

(3)       如何使用內聯函式和禁止內聯:

要讓乙個函式稱為內聯函式,有兩種方法:一種是把函式加上inline關鍵字;一種是在類的說明部分定義的函式,預設就是內聯的。

要禁止編譯器進行內聯,可以使用#pragma auto_inline編譯指令或者改變編譯引數。

(4)       內聯函式注意事項:

(1)       內聯函式一定會內聯展開嗎?答案是否定的。對於內聯函式,程式只是提供了乙個「內聯建議」,即建議編譯器把函式用內聯展開,但是真正是否內聯,是由編譯器決定的,對於函式體過大的函式,編譯器一般不會內聯,即使制定為內聯函式。

(2)       在內聯函式內部,不允許用迴圈語句和開關語句(if或switch)。內聯函式內部有迴圈和開關,也不會出錯,但是編譯器會把它當做非內聯函式的。

(3)       關鍵字inline必須與函式定義體放在一起才能使函式真正內聯,僅把inline放在函式宣告的前面不起任何作用。因為

inline

是一種用於實現的關鍵字,不是一種用於宣告的關鍵字。內聯函式的宣告是不需要加inline關鍵字的,內聯函式的定義是必須加inline的(除了類的定義部分的缺省內聯函式),儘管很多書宣告定義都加了,要注意理解宣告和定義的區別。

(4)       在乙個檔案中定義的內聯函式不能在另乙個檔案中使用。它們通常放在標頭檔案中共享。

(5)       內聯函式的定義必須在第一次呼叫之前。注意,這裡是定義之前,不僅僅是宣告之前。對於普通函式,可以在呼叫之前宣告,呼叫**之後具體定義(實現函式),但是內聯函式要實現內聯,必須先定義再呼叫,否則編譯器會把在定義之前呼叫的內聯函式當做普通函式進行呼叫。

(6)       說明:上面這些inline的注意事項,在程式設計時要自己注意,因為上面的注意事項不遵守很多並不會引起編譯錯誤,只是會導致寫了inline的函式不是內聯函式,從而與預期的目的不一樣。所以很多沒法用程式例項說明到底編譯器是按照inline還是非inline呼叫的,或許分析彙編**能看出,但是水平有限,就不多分析了。

(5)       一些關於內聯的參考文章:

關於c++的內聯函式

inline函式的一些總結

c++基礎--內聯函式

我們可以用inline來定義內聯函式,不過,任何在類的說明部分定義的函式都會被自動的認為是內聯函式。

內聯函式必須是和函式體申明在一起,才有效。像這樣的申明inline tablefunction(int i)是沒有效果的,編譯器只是把函式作為普通的函式申明,我們必須定義函式體。

inline tablefunction(int i) ;  

這樣我們才算定義了乙個內聯函式。我們可以把它作為一般的函式一樣呼叫。但是執行速度確比一般函式的執行速度要快。

我們也可以將定義在類的外部的函式定義為內聯函式,比如:

class tableclass;

inline int dec() 

int getnum();

}inline int tableclass::getnum() 

上面申明的三個函式都是內聯函式。在c++中,在類的內部定義了函式體的函式,被預設為是內聯函式。而不管你是否有inline關鍵字。

內聯函式在c++類中,應用最廣的,應該是用來定義訪問函式。我們定義的類中一般會把資料成員定義成私有的或者保護的,這樣,外界就不能直接讀寫我們類成員的資料了。對於私有或者保護成員的讀寫就必須使用成員介面函式來進行。如果我們把這些讀寫成員函式定義成內聯函式的話,將會獲得比較好的效率。

class sample

void settest(int i) 

}  當然,內聯函式也有一定的侷限性。就是函式中的執行**不能太多了,如果,內聯函式的函式體過大,一般的編譯器會放棄內聯方式,而採用普通的方式呼叫函式。這樣,內聯函式就和普通函式執行效率一樣了。 

下面這種方式直接呼叫內聯函式會有編譯錯誤:

class localstaticobject

inline bool localstaticobject::fibon_elem(int pos, int &elem)

//main 函式中呼叫

localstaticobject lso;

int init = 0;

int &elem = init;

bool flag = lso.fibon_elem(7, elem);

....

這樣會編譯錯誤:undefined reference to [方法名],去掉 fibon_elem 函式前的 inline 宣告就編譯通過了

C inline內聯函式探索

學過程式編譯的人知道,呼叫函式需要cpu執行引數壓棧 暫存器儲存與恢復 跳轉指令等操作,開銷比較大,高頻繁的呼叫函式對效能有影響,在c c 語言裡產生了macro巨集,由於巨集不是函式不會產生上述開銷,是一種比較好的優化,但巨集不是強型別程式設計,於是vc 產生了inline內聯函式,inline優...

C Inline 內聯函式小結

為解決 中頻繁呼叫小函式,消耗大量棧空間的問題,因而引入修飾符inline。執行速度比常規函式稍快,但以 膨脹為代價 函式內聯,節約的是處理函式呼叫機制的時長。若函式執行時間短,函式內聯的效益較高,反之效益降低 使用限制 1 不可遞迴使用 2 函式體較大的時候不適合使用 3 必須和函式定義放在一起才...

C inline內聯函式使用規則

inline函式的作用 定義 內聯函式避免頻繁呼叫函式對棧記憶體重複開闢所帶來的消耗,但是不能包含複雜的結構控制語句例如while switch,並且內聯函式本身不能直接呼叫遞迴函式 自己內部還呼叫自己的函式 在c 中,為了解決一些頻繁呼叫的小涵數大量消耗棧空間或者是叫棧記憶體的問題,特別的引入了i...