c語言學習小記 inline函式

2021-09-19 15:58:25 字數 2595 閱讀 8204

一、什麼是內聯函式

在c語言中,如果一些函式被頻繁呼叫,不斷地有函式入棧,即函式棧,會造成棧空間或棧記憶體的大量消耗。

為了解決這個問題,特別的引入了inline修飾符,表示為內聯函式。

棧空間就是指放置程式的區域性資料也就是函式內資料的記憶體空間,在系統下,棧空間是有限的,假如頻繁大量的使用就會造成因棧空間不足所造成的程式出錯的問題,函式的死迴圈遞迴呼叫的最終結果就是導致棧記憶體空間枯竭。

下面我們來看乙個例子:

#include //函式定義為inline即:內聯函式  

inline char* dbtest(int a)

int main()

} 上面的例子就是標準的內聯函式的用法,使用inline修飾帶來的好處我們表面看不出來,其實在內部的工作就是在每個for迴圈的內部任何呼叫dbtest(i)的地方都換成了(i%2>0)?"奇":"偶"這樣就避免了頻繁呼叫函式對棧記憶體重複開闢所帶來的消耗。

其實這種有點類似咱們前面學習的動態庫和靜態庫的問題,使 dbtest 函式中的**直接被放到main 函式中,執行for 迴圈時,會不斷呼叫這段**,而不是不斷地開闢乙個函式棧。

二、內聯函式的程式設計風格

1、關鍵字inline 必須與函式定義體放在一起才能使函式成為內聯,僅將inline 放在函式宣告前面不起任何作用。

如下風格的函式foo 不能成為內聯函式:

inline void foo(int x, int y); // inline 僅與函式宣告放在一起

void foo(int x, int y)

而如下風格的函式foo 則成為內聯函式:

void foo(int x, int y);

inline void foo(int x, int y) // inline 與函式定義體放在一起

所以說,inline 是一種「用於實現的關鍵字」,而不是一種「用於宣告的關鍵字」。一般地,使用者可以閱讀函式的宣告,但是看不到函式的定義。儘管在大多數教科書中內聯函式的宣告、定義體前面都加了inline 關鍵字,但我認為inline 不應該出現在函式的宣告中。這個細節雖然不會影響函式的功能,但是體現了高質量c++/c 程式設計風格的乙個基本原則:宣告與定義不可混為一談,使用者沒有必要、也不應該知道函式是否需要內聯。

2、inline的使用是有所限制的

inline只適合涵數體內**簡單的函式數使用,不能包含複雜的結構控制語句例如while、switch,並且內聯函式本身不能是直接遞迴函式(自己內部還呼叫自己的函式)。
三、慎用內聯

內聯能提高函式的執行效率,為什麼不把所有的函式都定義成內聯函式?如果所有的函式都是內聯函式,還用得著「內聯」這個關鍵字嗎?

內聯是以**膨脹(複製)為代價,僅僅省去了函式呼叫的開銷,從而提高函式的執行效率。如果執行函式體內**的時間,相比於函式呼叫的開銷較大,那麼效率的收

獲會很少。另一方面,每一處內聯函式的呼叫都要複製**,將使程式的總**量增大,消耗更多的記憶體空間。

以下情況不宜使用內聯:

(1)如果函式體內的**比較長,使用內聯將導致記憶體消耗代價較高。

(2)如果函式體內出現迴圈,那麼執行函式體內**的時間要比函式呼叫的開銷大。

乙個好的編譯器將會根據函式的定義體,自動地取消不值得的內聯(這進一步說明了inline 不應該出現在函式的宣告中)。

總結:

因此,將內聯函式放在標頭檔案裡實現是合適的,省卻你為每個檔案實現一次的麻煩.而所以宣告跟定義要一致,其實是指,如果在每個檔案裡都實現一次該內聯函式的話,那麼,最好保證每個定義都是一樣的,否則,將會引起未定義的行為,即是說,如果不是每個檔案裡的定義都一樣,那麼,編譯器展開的是哪乙個,那要看具體的編譯器而定.所以,最好將內聯函式定義放在標頭檔案中.

今天在看hal層的標頭檔案的時候,看到static inline int sensors_open,對inline有些不了解,在這記錄一下

inline

關鍵字inline表明要優化函式的可執行**,這可以通過將函式的**合併到呼叫程式的**中來實現。linux核心使用的inline函式大多被定義為static 型別。乙個"static inline"函式促使編譯程式嘗試著將其**插入到所有呼叫它的程式中。

這一合併能夠免除函式呼叫的任何開銷,#define語句也可以排除額外的函式呼叫。

另外,使用inline會增加二進位制映像的大小,而這會降低訪問cpu快取記憶體的速度,所以不能在所有的函式定義中使用它。

都是以空間換時間(解釋就是講這段inline程式直接展開編譯進去,因此會增加編譯檔案的空間,換取的時間呢,就是不用頻繁的壓棧出棧,從而節省時間),巨集定義與內聯函式的區別是:巨集定義不會進行型別檢查,而內聯函式會進行型別檢查;當構建程式的時候,尤其是之前經常定義static函式,可以將這些函式中行數在3行以內的改為內聯函式,這樣就會提高程式的執行速度,但會增加程式編譯後檔案的大小;遞迴函式不能用inline,函式太大不要用inline;c++中類的成員函式,如果在類中就給出函式的定義,那麼這個函式就是inline函式;

C語言學習 函式

先定義,後使用。型別名 函式名 或者 型別名 函式名 void 1 型別名這裡表示的是函式的返回值型別,也可以用void,表示不返回函式值 2 函式體包含宣告部分和語句部分 型別名 函式名 形式引數列表 1 形式引數列表,比如 int x,int y 型別名 函式名 比如 void dummy 單獨...

c語言學習小記 sizeof與strlen的區別

sizeof是乙個單目運算子 而strlen是乙個函式 從字面意義來理解 sizeof的 size 是大小的意思,是用來計算某種資料型別的大小,即所佔的位元組數 strlen的 len 是長度的意思,是用來計算字串的長度 例 char str 7 hello int arr 3 sizeof str...

go語言學習小記10

相比較 c 而言,go中的 switch 結構使用上更加靈活。它接受任意形式的表示式 switch var1變數 var1 可以是任何型別,而 val1 和 val2 則可以是同型別的任意值。型別不被侷限於常量或整數,但必須是相同的型別 或者最終結果為相同型別的表示式。前花括號並且 switch i...