這裏記錄一下函數指針的學習。c++
函數指針顧名思義就是指向一個函數的指針,函數指針能夠理解成指向函數入口地址的指針。函數指針的定義以下:數組
bool (*pf)(int,int);//指向一個形參爲(int,int),返回值爲bool值的指針,記得使用括弧 bool* pf(int,int);//該形式並非函數指針,而是返回一個指針類型的函數
使用以下:函數
bool (*pf)(int,int); bool check(int a,int b){ return a==b; } bool bigger(int a,int b){ return a>b; } int main(int argc, char* argv[]) { int a=34,b=34; pf=check;//等價於pf=✓ cout<<pf(a,b)<<endl;//pf(a,b)等價於(*pf)(a,b) b=32; cout<<pf(a,b)<<endl; pf=bigger; cout<<pf(a,b)<<endl; b=34; cout<<pf(a,b)<<endl; return 0; } //輸出結果 //1 //0 //1 //0
對於函數指針的定義而言,理解起來有點費勁,使用C++ Primer書中的解釋理解:學習
對於函數指針,能夠從名字開始觀察,pf前面有個*,所以pf是指針;右側是形參列表,標識pf指向的是一個函數;再觀察左邊,返回的是一個bool類型。所以pf就是一個指向函數的指針,該函數有兩個形參,返回類型爲bool值。指針
函數指針也能夠充當形參在方法中傳入:code
bool bigger(int a,int b){ return a>b; } bool (*pf)(int,int); void testConfig(int k,bool pf(int a,int b)){ bool value=pf(12,1); cout<<k<<" "<<value<<endl; } bool check(int a,int b){ return a==b; } int main(int argc, char* argv[]) { int a=34,b=34; int *p=&a; testConfig(12, bigger); testConfig(12, check); return 0; } //result //12 1 //12 0
因爲使用上述方式聲明函數指針顯得冗長繁瑣,因此能夠經過typedef以及decltype來簡化咱們的代碼:ip
bool check(int& a,int b){ return a==b; } bool bigger(int a,int b){ return a>b; } bool (*pf)(int,int); void testConfig(int k,bool pf(int a,int b)){ bool value=pf(12,1); cout<<k<<" "<<value<<endl; } typedef int(*po) (int,int); decltype(bigger) *dePo; int main(int argc, char* argv[]) { int a=34,b=34; int *p=&a; testConfig(12, dePo); testConfig(12, check); return 0; }
上述代碼中能夠看到,使用dePo代替了指向bigger()函數的函數指針。編譯器
須要注意的是decltype返回函數類型,此時是不會講函數類型自動轉換爲指針的,須要顯式在在dePo前面加個*來標明對應爲指針類型。編譯
tip:class
須要注意decltype()和decltype(())的區別(推導四規則):
int i=10; decltype(i) a; //a推導爲int decltype((i))b=i;//b推導爲int&,必須爲其初始化,不然編譯錯誤
和數組相似,雖然不能返回一個函數,可是能返回指向函數類型的指針。須要注意的是,咱們必須把返回類型寫成指針的形式,編譯器不會自動的將函數返回類型當作對應指針的類型處理:
bool bigger(int a,int b){ return a>b; } using PF= bool (*)(int,int);//PF爲函數指針 using PFD=bool(int,int);//PFD是函數類型,不是指針 PFD *f1(int){//顯示指定返回類型爲函數指針 return bigger; } PF f2(int,bool pf(int,int)){ // ... return bigger; }
咱們也能夠不用using來直接聲明返回的函數指針:
bool (*f3(int a))(int b,int c){ return bigger; }
這樣就有點繞了,能夠按照由內向外的順序進行閱讀,f3有形參a,說明是一個函數,前面有一個*號,因此返回的是一個指針,而指針有參數b,c,說明這個指針指向一個函數,這個函數的返回值爲布爾值。
使用尾置類型可能更好理解一些:
auto f4(int)->int(*)(int,int);