函式的地址是存盤其機器語言代碼的記憶體的開始地址,可以撰寫將另一個函式的地址作為引數的函式,它允許在不同的時間傳遞不同函式的地址,這意味著可以在不同的時間使用不同的函式,
1 函式指標型別
宣告指向函式的指標時,必須指定函式的回傳型別以及函式的特征標(引數串列),可以首先撰寫這種函式的原型,然后用 (*pf) 替換函式名,這樣 pf 就是這類函式的指標,以下面的程式為例,要獲取函式的地址,只需使用函式名即可(后面不跟引數),這與陣列地址有幾分相似,函式指標 pf 的型別是 double (*)(int),由于 pf 是指向 pam() 函式的指標,因此 (*pf) 是函式,使用函式指標呼叫函式時,C++ 將 pf 與 (*pf) 看作是等價的(雖然前者是函式指標,后者是函式),將 pf() 用作函式呼叫與將 (*pf)() 用作函式呼叫,效果一樣,
//函式原型
double pam(int);
//宣告對應的函式指標
double (*pf)(int);
//賦值,也可在宣告時進行
pf = pam;
//使用函式指標呼叫函式,以下幾種方式等效
double x = pam(4); //方式一
double x = (*pf)(4); //方式二
double x = pf(4); //方式三
//輸出函式地址
cout << pam; //值為0x001F1384
cout << pf; //值為0x001F1384
對函式指標進行賦值時,對應函式的特征標和回傳型別必須與 pf 相同,如果不相同,編譯器將拒絕這種賦值,例如函式指標型別 const double * (*)(const double *, int) 與下面幾種函式匹配,它們的特征標看似不同,但實際上相同,還可使用 auto 關鍵字自動推斷函式指標的型別,
//函式原型
const double * f1(const double ar[], int n);
const double * f2(const double * ar, int n);
const double * f3(const double [], int);
const double * f4(const double *, int);
//宣告函式指標
const double * (*pf)(const double *, int);
//賦值
pf = f1;
pf = f2;
pf = f3;
pf = f4;
//可使用自動型別推斷
auto pff = f1;
假設要設計一個名為 estimate() 的函式,用于估算撰寫指定行數的代碼所需的時間,而且允許每個程式員提供自己的演算法來估算時間,此時可將函式地址作為該函式的輸入引數,其函式原型可使用如下宣告,需保證每個程式員提供的函式特征標和回傳型別都一致且與 double (*)(int) 匹配,
//將函式指標作為函式引數
void estimate(int lines, double (*pf)(int));
2 函式指標陣列
指向函式指標陣列的指標通常用于類的虛方法實作中,細節通常由編譯器自動處理,如下程式所示,函式指標陣列大體性質與一維陣列相似,其中需要注意的是:
- 運算子
()與[]的優先級比*要高,因此需在合適的地方使用括號()提高*的優先級, - 無法將指標算術運用于函式名,即出現
fb+1或arrpf[i]+1時編譯器會報錯, - 無法將
sizeof()運用于函式名fb,但可用于arrpf[i],即出現sizeof(fb)時編譯器會報錯,但sizeof(arrpf[i])則不會,
//函式原型
double fa(int);
double fb(int);
double fc(int);
double fd(int);
//宣告并初始化函式指標陣列
double (*arrpf[4])(int) = {fa,fb,fc,fd};
//宣告并初始化指向函式指標陣列第一個元素的指標,以下三種方式對arrpfb等效
double (**arrpfb)(int) = arrpf; //方式一
double (**arrpfb)(int) = &arrpf[0]; //方式二
auto arrpfb = &arrpf[0]; //方式三
//宣告并初始化指向整個函式指標陣列的指標,以下兩種方式對arrpfc等效
double (*(*arrpfc)[4])(int) = &arrpf; //方式一
auto arrpfc = &arrpf; //方式二
//呼叫函式fb,以下幾種方式等效
int x = 5;
double y = fb(x);
double y = arrpf[1](x);
double y = (*arrpf[1])(x);
double y = (*(arrpf+1))(x);
double y = (**(arrpf+1))(x);
double y = arrpfb[1](x);
double y = (*arrpfb[1])(x);
double y = (*(arrpfb+1))(x);
double y = (**(arrpfb+1))(x);
double y = (*arrpfc)[1](x);
double y = (*(*arrpfc)[1])(x);
double y = (*(*arrpfc+1))(x);
double y = (**(*arrpfc+1))(x);
//應用指標算術時單位1表示的位元組數(32系統)
cout << int(arrpf+1)-int(arrpf); //結果為4
cout << int(&arrpf[0]+1)-int(&arrpf[0]);//結果為4
cout << int(&arrpf+1)-int(&arrpf); //結果為16
cout << int(arrpfb+1)-int(arrpfb); //結果為4
cout << int(arrpfc+1)-int(arrpfc); //結果為16
//應用sizeof()獲得記憶體量大小(32系統)
cout << sizeof(arrpf); //結果為16
cout << sizeof(&arrpf[0]);//結果為4
cout << sizeof(&arrpf); //結果為4
cout << sizeof(arrpf[0]); //結果為4
cout << sizeof(arrpfb); //結果為4
cout << sizeof(arrpfc); //結果為4
3 使用 typedef 進行簡化
可將 typedef 關鍵字用于函式指標型別,簡化程式的撰寫,如下所示,此時 p_fun 就是函式指標型別 double (*)(int) 的別名,上述陣列以及指標宣告可采用以下等效形式,
//指定函式指標別名
typedef double (*p_fun)(int);
//宣告并初始化函式指標陣列,與前面等效
p_fun arrpf[4] = {fa,fb,fc,fd};
//宣告并初始化指向函式指標陣列第一個元素的指標,與前面等效
p_fun* arrpfb = &arrpf[0];
//宣告并初始化指向整個函式指標陣列的指標,與前面等效
p_fun (*arrpfc)[4] = &arrpf;
本文作者:木三百川
本文鏈接:https://www.cnblogs.com/young520/p/16691042.html
著作權宣告:本文系博主原創文章,著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請附上出處鏈接,遵循 署名-非商業性使用-相同方式共享 4.0 國際版 (CC BY-NC-SA 4.0) 著作權協議,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/507113.html
標籤:C++
