C++程式的函式指標:實操來了

千鋒Python唐小強發表於2019-11-13

先看看這段程式碼:

#includeusing std::cout;using std::endl; inline int min(int a,int b){return (a>b) ? b : a;} int Min(int a,int b,int (*pf)(int,int))//可以使用預設引數:int Min(int a,int b,int (*pf)(int,int)=min){return pf(a,b); //透過函式指標來呼叫函式,也可以寫為 //return (*pf)(a,b);作用是一樣的。} int main(int argc, char* argv[]){int i=1;int j=10; int r=Min(i,j,min); //如果使用預設引數的話,可以寫成:int r=Min(i,j);cout<<1r<1<1endl;
return 0;
}

其中int (*pf)(int,int)定義了一個返回值為int,引數為兩個int的函式指標。如果不在*pf上加括號的話,即:

int *pf(int,int),

編譯器會把它解釋為一個返回值為整型指標,引數為兩個int的函式。

可以用typedef來簡化程式碼:

#includeusing std::cout;using std::endl;typedef int (*PF)(int,int);//這行程式碼是關鍵,相當與把上個例子中的函式指標宣告為一種資料型別。 inline int min(int a,int b){return (a>b) ? b : a;}int Min(int a,int b,PF f) //PF f定義f為和上個例子中一樣的函式指標。{return f(a,b);}int main(int argc, char* argv[]){int i=1;int j=10;int r=Min(i,j,min);cout<<1r<1<1endl;
return 0;
}

也可以提供一個用模板實現的函式指標:

#includeusing std::cout;using std::endl;inline int min(int a,int b){return (a>b) ? b : a;}templateT Min(T a,T b,T (*pf)(T,T)){return pf(a,b);}int main(int argc, char* argv[]){int i=1;int j=10;int r=Min(i,j,min); //int r=Min(i,j,min); 這種形式編譯器會報錯:Expression syntaxcout<<1r<1<1endl;
return 0;
}

當然,這個指標指向的函式也可用模板來實現:

#includeusing std::cout;using std::endl; templateinline T min(T a,T b){return (a>b) ? b : a;}templateT Min(T a,T b,T (*pf)(T,T)){return pf(a,b);}int main(int argc, char* argv[]){long i=2000000;long j=1000000;//使用時有三種形式:long r=Min(i,j,min);//第一種。注意這裡在min後一定要加,否則編譯器將報錯://Could not find a match for "Min(long,long,T(*)(T,T)"//第二種:long r=Min(i,j,min);//第三種:long r=Min(i,j,min);//其實質是一樣的。cout<<1r<1<1endl;
return 0;
}

不過我不能用typedef使程式碼更為簡便,就像下面這種形式:

template

typedef T (*PF)(T,T);

編譯器會提示:Templates must be classes or functions

另外還可以使用函式指標的陣列:

#includeusing std::cout;using std::endl;inline int min(int a,int b){return (a>b) ? b : a;}inline int max(int a,int b){return (a>b) ? a : b;}int main(int argc, char* argv[]){int i=1;int j=10; int (*pf[2])(int,int);//擁有兩個元素的函式指標陣列,每個元素是返回值為int,引數為兩個int的函式指標。pf[0]=min;pf[1]=max; int r1=pf[0](i,j);int r2=pf[1](i,j);cout<<1r1<1<1endl;cout<1<1r2<1<1endl;
return 0;
}

指向過載函式的指標也是值得注意的:#include using std::cout;using std::endl;

inline void print(int a){ cout<<1a<1<1endl;}inline void="" print(long="" b){="" cout<1<1b<1<1endl;}
int main(int argc, char* argv[]){ int i=1; long m=100000;
 void (*pf1)(int)=print; void (*pf2)(long)=print;
 pf1(i); pf2(m);

return 0;}程式執行的很成功。因為編譯器會自動查詢所有的過載函式,以找到和函式指標指向的函式具有相同的返回型別和參數列的函式。

如上我們可知宣告一個給定函式的函式指標的一般規則:即這個函式指標的返回型別和參數列必須和給定的函式相同。要注意省略號也是函式型別的一部分,int function1(int,...)與int function2(int)需要兩個不同的函式指標。其實函式名就是指向該函式的指標,對於int function(int)來說,function就是它的指標。我們可用這個特性對函式指標進行初始化:int (*pf)(int)=function;

取地址運算子也可以用在函式名上,上面的程式碼和int (*pf)(int)=&function的作用是一樣的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69923331/viewspace-2663938/,如需轉載,請註明出處,否則將追究法律責任。

相關文章