C 中的內聯函式inline總結

2021-08-09 03:18:04 字數 2953 閱讀 2216

**:

突然看到c++primer中講到,對於vector的乙個迴圈,呼叫語句:(示例**i=v.begin()不是很規範,雖然不會出錯,客官請將就著看)

[cpp]view plain

copy

for(

inti=v.begin() ; i  

對於size()的呼叫,其實是內聯。想到以前貌似是看《高質量c/c++程式設計》時,提過,在迴圈時,可以採用變數儲存v.size()的值,以減少每個迴圈的呼叫開支。於是決定一搜,順便總結之。

1、inline的引出

考慮下列min()函式(例子來自c++primer第三版303頁)

[cpp]view plain

copy

intmin( 

intv1, 

intv2 )    

為這樣的小操作定義乙個函式的好處是:

a.如果一段**包含min()的呼叫,那閱讀這樣的**並解釋其含義比讀乙個條件操作符的例項,可讀性會強很多。

b.改變乙個區域性化的實現比更改乙個應用中的300個出現要容易得多

c.語義是統一的,每個測試都能保證相同的方式實現

d.函式可以被重用,不必為其他的應用重寫**

不過,將min()寫成函式有乙個嚴重的缺點:呼叫函式比直接計算條件操作符要慢很多。那怎麼能兼顧以上優點和效率呢?c++提供的解決方案為inline(內聯)函式

2、inline的原理:**替代

在程式編譯時,編譯器將程式中出現的內聯函式的呼叫表示式用內聯函式的函式體來進行替代。

例如,如果乙個函式被指定為inline 函式則它將在程式中每個呼叫點上被內聯地展開例如

[cpp]view plain

copy

intminval2 = min( i, j );  

在編譯時被展開為

[cpp]view plain

copy

intminval2 = i < j << i : j;  

則把min()寫成函式的額外執行開銷從而被消除了。

3、inline的使用

讓乙個函式成為內聯函式,隱式的為在類裡定義函式,顯式的則是在函式前加上inline關鍵字說明。

4、使用inline的一些注意事項

a.從inline的原理,我們可以看出,inline的原理,是用空間換取時間的做法,是以**膨脹(複製)為代價,僅僅省去了函式呼叫的開銷,從而提高函式的執行效率。如果執行函式體內**的時間,相比於函式呼叫的開銷較大,那麼效率的收穫會很少。所以,如果函式體**過長或者函式體重有迴圈語句,if語句或switch語句或遞迴時,不宜用內聯

b.關鍵字inline 必須與函式定義體放在一起才能使函式成為內聯,僅將inline 放在函式宣告前面不起任何作用。內聯函式呼叫前必須宣告。《高質量c/c++程式設計》裡乙個例子。

[cpp]view plain

copy

inline

void

foo(

intx, 

inty); 

// inline 僅與函式宣告放在一起

void

foo(

intx, 

inty)    

以上**不能成為內聯函式,而以下則可以

[cpp]view plain

copy

void

foo(

intx, 

inty);  

inline

void

foo(

intx, 

inty) 

// inline 與函式定義體放在一起  

所以說,inline 是一種「用於實現的關鍵字」,而不是一種「用於宣告的關鍵字」。對於以上例子,林銳還建議,只在定義前加上inline,而不是在宣告和定義前都加,因為這能體現高質量c++/c 程式設計風格的乙個基本原則:宣告與定義不可混為一談。

c.inline對於編譯器來說只是乙個建議,編譯器可以選擇忽略該建議。換句話說,哪怕真的寫成了inline,也沒有任何錯誤的情況下,編譯器會自動進行優化。所以當inline中出現了遞迴,迴圈,或過多**時,編譯器自動無視inline宣告,同樣作為普通函式呼叫。

總結下:

樓主覺得可以將內聯理解為c++中對於函式專有的巨集,對於c的函式巨集的一種改進。對於常量巨集,c++提供const替代;而對於函式巨集,c++提供的方案則是inline。在c中,大家都知道巨集的優勢,編譯器通過複製巨集**的方式,省去了引數壓棧,生成彙編的call呼叫,返回引數等操作,雖然存在一些安全隱患,但在效率上,還是很可取的。

不過函式巨集還是有不少缺陷的,主要有以下:

a.在複製**時,容易出現一想不到的邊際效應,比如經典的

[cpp]view plain

copy

#define max(a, b) (a) > (b) ? (a) : (b)

在執行語句:

[cpp]view plain

copy

result = max(i, j) + 2 ;  

時,會被解釋為

[cpp]view plain

copy

result = (i) > (j) ? (i) : (j) + 2 ;  

b.使用巨集,無法進行除錯,雖然windows提供了assert巨集

c.使用巨集,無法訪問類的私有成員

所以,c++ 通過內聯機制,既具備巨集**的效率,又增加了安全性,還可以自由操作類的資料成員,算是乙個比較完美的解決方案。

關於巨集,大家還可以參考下:更原創,內容豐富,可取,總結了各家觀點,稍微整理了下,不過還是蠻清楚的。

就這樣吧,菜鳥goes on ~~~

inline函式 C 內聯函式 inline

inline要起作用,必須要與函式定義放在一起,而不是函式的宣告 inline 當編譯器處理呼叫內聯函式的語句時,不會將該語句編譯成函式呼叫的指令,而是直接將整個函式體的 插人呼叫語句處,就像整個函式體在呼叫處被重寫了一遍一樣,在執行時是順序執行,而不會進行跳轉。優點 內聯函式沒有執行函式呼叫的開銷...

C 中的內聯函式inline

c 中使用內聯函式可以減少函式來回跳轉的次數,有效地提高程式執行的速度。但是假如函式體有很多 但是需要重複呼叫該函式很多次的話,那麼不斷地複製該函式體的 將會造成程式的增大,所以我們需要將函式的宣告和定義分開。c 中編譯器不會建立真正的函式,而只是將這個內聯函式中的所有 拷貝到呼叫函式中。語法 in...

C 中的inline內聯函式

inline 關鍵字可以只在函式定義處新增,也可以只在函式宣告處新增,也可以同時新增 但是在函式宣告處新增 inline 關鍵字是無效的,編譯器會忽略函式宣告處的 inline 關鍵字。也就是說,inline 是一種 用於實現的關鍵字 而不是一種 用於宣告的關鍵字 儘管大多數教科書中在函式宣告和函式...