C++函式呼叫過程和內建函式詳解
阿新 • • 發佈:2018-12-31
上圖表示
函式呼叫過程:①程式先執行函式呼叫之前的語句;②流程的控制轉移到被呼叫函式入口處,同時進行引數傳遞;③執行被呼叫函式中函式體的語句;④流程返回呼叫函式的下一條指令處,將函式返回值帶回;⑤接著執行主調函式未執行的語句。
這樣就要求在轉到被呼叫函式之前,要 記下當時執行的指令的地址,還要“保護現場”(記下當時有關的資訊),方便在函式呼叫之後繼續執行。在函式呼叫之後,流程返回到先前記下的地址處,並且根據記下的資訊“恢復現場”,然後繼續執行。這一些都會花費一定的時間。如果有的函式需要頻繁的使用,則所用時間會很長,從而降低程式的執行效率。有些實用程式對效率是有要求的,要求系統的響應世間短。這就希望儘量壓縮時間的開銷。
C++提供了一種提高效率的方法,即在編譯的時候將所呼叫的程式碼直接嵌入到主調函式中,而不是將流程轉出去。這種嵌入到主調函式中的函式稱為 內建函式 (inline function),又稱
內嵌函式。有些書把它譯成
行內函數。
用法:在函式首行的左端加一個關鍵字inline即可。 例項:
使用內建函式可以節省執行時間,但卻增加了目標程式的長度。假設要呼叫10次max函式,則編譯時先後10次將max程式碼複製並插入main函式,這就增加了目標檔案main函式的長度。因此一般只將規模很小(一般為5個語句以下)而使用頻繁的函式(如定時採集資料的函式宣告為內建函式)。在函式規模很小的情況下,函式呼叫的時間開銷可能相當於甚至超過執行函式本身的時間,把它定義為內建函式,可 大大減少程式的執行時間 。
內建函式中不能包括複雜的控制語句,如迴圈語句和switch語句。
對函式做inline宣告,只是程式設計者對編譯系統提出的一個建議,它是建議性的,而不是指令性的。並非指定為inline,編譯系統必須這樣做。它是根據具體情況決定的。例如對前面提到的包含迴圈語句和switch語句的函式或一個遞迴函式是無法進行程式碼置換的,又如一個1000行的函式,也不太可能在呼叫點展開。此時編譯系統就會忽略inline宣告,而按普通函式處理。 總結, 只有規模較小而又頻繁呼叫的簡單函式,才適合於宣告為inline函式。
這樣就要求在轉到被呼叫函式之前,要 記下當時執行的指令的地址,還要“保護現場”(記下當時有關的資訊),方便在函式呼叫之後繼續執行。在函式呼叫之後,流程返回到先前記下的地址處,並且根據記下的資訊“恢復現場”,然後繼續執行。這一些都會花費一定的時間。如果有的函式需要頻繁的使用,則所用時間會很長,從而降低程式的執行效率。有些實用程式對效率是有要求的,要求系統的響應世間短。這就希望儘量壓縮時間的開銷。
C++提供了一種提高效率的方法,即在編譯的時候將所呼叫的程式碼直接嵌入到主調函式中,而不是將流程轉出去。這種嵌入到主調函式中的函式稱為 內建函式
用法:在函式首行的左端加一個關鍵字inline即可。 例項:
if (c > a){a = c;}return a;}由於定義函式時指定它為內建函式,因此編譯系統在遇到函式呼叫“max(i,j,k)”時,就用max函式體的程式碼代替“max(i,j,k)”,同時將 實參代替形參。這樣程式第10行“m = max(i,j,k);"就被置換成#include <iostream> using namespace std; inline int max(int,int,int);//宣告函式 int main() { int i = 10; int j = 20; int k = 30; int m; m = max(i,j,k); cout << "max=" << m << endl; return 0; } inline int max(int a; int b; int c)//定義max為內建函式 { //求a,b,c中的最大者 if (b > a) { a = b; }
if(j > i) i = j;
if(k > i) i = k;
m = i;
注意,可以在宣告函式和定義函式時同時寫inline,也可以只是其中一處宣告inline,效果相同,都能按內建函式處理。
使用內建函式可以節省執行時間,但卻增加了目標程式的長度。假設要呼叫10次max函式,則編譯時先後10次將max程式碼複製並插入main函式,這就增加了目標檔案main函式的長度。因此一般只將規模很小(一般為5個語句以下)而使用頻繁的函式(如定時採集資料的函式宣告為內建函式)。在函式規模很小的情況下,函式呼叫的時間開銷可能相當於甚至超過執行函式本身的時間,把它定義為內建函式,可 大大減少程式的執行時間
內建函式中不能包括複雜的控制語句,如迴圈語句和switch語句。
對函式做inline宣告,只是程式設計者對編譯系統提出的一個建議,它是建議性的,而不是指令性的。並非指定為inline,編譯系統必須這樣做。它是根據具體情況決定的。例如對前面提到的包含迴圈語句和switch語句的函式或一個遞迴函式是無法進行程式碼置換的,又如一個1000行的函式,也不太可能在呼叫點展開。此時編譯系統就會忽略inline宣告,而按普通函式處理。 總結, 只有規模較小而又頻繁呼叫的簡單函式,才適合於宣告為inline函式。