天天看點

(一〇二)内聯函數

元旦了,各種打不開部落格。元旦結束,部落格好了,是因為元旦放假程式員都回家了嘛?

————————————————————————————————

内聯函數和普通函數有所差別。

普通函數需要①函數定義②函數原型③函數調用,具體調用形式是,先調用時,儲存目前函數的記憶體位址(假設為位址a),然後調用函數,跳到被調用函數的記憶體位址(位址b),然後在位址b處依次執行,等執行完被調用的函數(或許還有傳回值),再傳回之前儲存的位址a處。

内聯函數,可以省略②函數原型(也可以不省略),但需要在函數定義和函數原型的函數頭之前加上關鍵字inline(如果省略函數原型的話,則一般将函數定義放在函數原型的地方),

他的機制,是把函數代碼,放在函數調用時的記憶體位址處,這樣的話,無需像普通函數那樣,從位址a處跳到位址b處,調用完再跳回來,而是位址a處之後的記憶體位置,就是原本是位址b處函數的代碼内容。就像直接将函數指令放在調用處一樣。

例如:

int main()

{

int a=x(1);

return 0;

}

int x(int m)

return m+3;

在普通函數時,int a的記憶體位址是位址a,而x函數被儲存在位址b處(注意,b和a并不一定相鄰,或者說,幾乎不會相鄰)。于是程式通路記憶體時的順序:位址a——位址b——位址a這樣。

而在内聯函數時,在int x(int m)之前加上inline,在main函數中,有點類似于:

int a={ 1 + 3 };

這樣的形式。

由于内聯函數是直接放在main函數中(而不是調用的時候才占用記憶體),是以,使用内聯函數更耗費記憶體。但相對而言,使用内聯函數的優點則是速度更快(因為不用在記憶體之中跳來跳去)。

但,由于在記憶體位址中跳來跳去速度其實很快,是以節省的時間的絕對值,并不大,除非該函數經常被調用(每次節約0.01秒,100次就是1秒了)。

内聯函數的優點:速度更快——适合執行代碼時間很短的函數;

内聯函數的缺點:占用記憶體更多——不适合較長的函數。

編譯器不允許使用内聯函數的兩種情況:

①遞歸函數——内聯函數不允許自己調用自己;

②函數過大。

内聯函數的使用方式:

①在函數原型和函數定義的函數頭之前加上關鍵字inline即可;

②可省略函數原型,若省略,則将函數定義放置于函數原型處較好;

③其他同普通函數。

如代碼:

輸出:

與内聯函數對應的宏:

在c語言中,使用預處理器語句#define來提供宏——内聯代碼的原始實作。

例如宏:#define squar(x) x*x;

宏的特點是文本替換,而不像内聯函數那樣是函數調用——也就意味着,沒有括号的情況下,結果和内聯函數的結果不同。

如define的代碼:

使用内聯函數的代碼:

由上述兩個例子可以看出,#define宏的效果,和inline内聯函數的機制完全不同。

#define是文本替換,将括号裡的内容直接指派到表達式之中——而不是括号裡表達式的結果。

inline是像函數調用那樣,将表達式的值得出值的結果後,再放入函數内部的表達式之中。

特别是比如說:#define mm(m) m*m*m; 這樣的宏,

當遇見調用int a=1; int b=mm(a++);時,

在代碼中,b=1*2*3=6,

而不是内聯函數的b=1*1*1(因為a++是先執行完這行代碼之後,a=a+1);

繼續閱讀