C++中的行內函數,預設引數和佔位引數
說明:裡面的示例程式碼有些被註釋掉了,想執行時要去掉註釋
#include "iostream"
using namespace std;
/**
內聯函數出現的原因:
C++中的const常量可以替代巨集常數定義,如:const int A = 3;#define A 3
C++中推薦使用行內函數替代巨集程式碼片段
C++中使用inline關鍵字宣告行內函數
行內函數宣告時inline關鍵字必須和函式定義結合在一起,否則編譯器會直接忽略內聯請求
結論:
1、行內函數在編譯時直接將函式體插入函式呼叫的地方
2、inline知識一種請求,編譯器不一定允許這種請求
3、行內函數省去了普通函式呼叫時壓棧,跳轉和返回的開銷
**/
/**
inline void printA()
{
int a = 10;
cout<<"a"<<a<<endl;
}
void main()
{
printA();
system("pause");
}
**/
/**
說明:
1、必須inline int myfunc(int a,int b)和實現的地方,寫在一塊。
2、C++編譯器可以將一個函式進行內聯編譯 被C++編譯器內聯編譯的函式叫做行內函數
行內函數在最終生成的程式碼中是沒有定義的 C++編譯器直接將函式體插入函式呼叫的地方
行內函數沒有普通函式呼叫時的額外開銷(壓棧、跳轉、返回)
3、C++編譯器不一定準許函式的內聯請求
4、行內函數時一種特殊的函式,具有普通函式的特徵(引數檢查,返回型別等)
行內函數是對編譯器的一種請求,因此編譯器可能拒絕這種請求
行內函數有編譯器處理,直接將編譯後的函式體插入呼叫的地方
巨集程式碼片段由前處理器處理,進行簡單的文字替換,沒有任何編譯過程
5、現代C++編譯器能夠進行編譯優化、因此一些函式即使沒有inline宣告,也可能被編譯器內聯編譯
另外,一些現代C++編譯器提供了擴充套件語法,能夠對函式進行強制內聯 如:g++中的 attribute((always inline))屬性
6、C++中內聯編譯的限制:不能存在任何形式的迴圈語句 不能存在過多的條件判斷語句
函式體不能過於龐大 不能對函式進行取址操作 函式內聯宣告必須在呼叫語句之前
編譯器對於行內函數的限制並不是絕對的,行內函數相對於普通函式的優勢只是省去了函式呼叫時壓棧,跳轉和返回的開銷
因此,當函式體的執行開銷遠大於壓棧,跳轉和返回所用的開銷時,那麼內聯將無意義
結論:
1、行內函數在編譯時直接將函式體插入函式呼叫的地方
2、inline只是一種請求,編譯器不一定允許這種操作
3、行內函數省去了普通函式呼叫時壓棧、跳轉和返回的開銷
**/
//帶引數的巨集
#define MYFUNC(a,b) ((a)<(b)?(a):(b))
inline int myfunc(int a,int b)
{
return a<b? a:b;
}
/**
int main()
{
int a = 1;
int b = 3;
//int d = myfunc(++a,b);//測試行內函數時去掉註釋
int c = MYFUNC(++a,b);//==>巨集替換並展開 ((++a)<(b)?(++a):(b))
printf("a=%d\n",a);
printf("b=%d\n",b);
printf("c=%d\n",c);
//printf("d=%d\n",d);
system("pause");
}
*/
/**============預設餐宿======================**/
/**
C++中可以在函式宣告時為引數提供一個預設值,當函式呼叫時沒有指定這個引數的值,編譯器會自動用預設值代替
函式預設引數的規則:
只有引數列表後面部分的引數才可以提供預設引數值
一旦在一個函式呼叫中開始使用預設引數值,那麼這個引數後的所有引數都必須使用預設引數值
*/
void myPrint(int x = 3)
{
cout<<"x"<<x<<endl;
}
void myPrint(int m,int x = 3,int y = 4)
{
cout<<"x"<<x<<endl;
}
/**
函式佔位引數
佔位引數只有引數型別宣告,而沒有引數名宣告
一般情況下,在函式體內部無法使用佔位引數
**/
void func1(int a,int b,int)//呼叫時必須寫夠引數
{
cout<<"a:"<<a<<" b:"<<b<<endl;
}
/**
預設引數和佔位引數
可以將佔位引數與預設引數結合起來使用
意義:
為以後程式的擴充套件留下線索 相容C語言程式中可能出現的不規範寫法
C++可以宣告佔位引數,佔位符引數一般用於程式擴充套件和對C程式碼的相容
**/
int func2(int a,int b,int = 0)
{
cout<<"a:"<<a<<" b:"<<b<<endl;
return 0;
}
void main()
{
//預設引數
//myPrint(4);
//myPrint();
//佔位引數
func1(1,2,3);
//佔位引數和預設引數
func2(4,5);
func2(1,2,3);
system("pause");
return;
}