一、格式
例如:
- //指針名為pf,指向一個傳回值為bool,參數為兩個const string&的函數
- bool (*pf)(const string&, const string&);
- //這個不是函數指針,而是一個傳回值為bool*的pf函數
- bool *pf(const string&, const string&);
二、函數指針的指派
- 可以直接将函數名指派給函數指針,或者在函數名前加&符号都可以
- bool lengthCompare(const string&, const string&);
- bool (*pf)(const string&, const string&);
- int main()
- {
- pf = lengthCompare; //正确
- pf = &lengthCompare;//正确
- return 0;
- }
三、通過函數指針調用函數
調用方式
- 如果pf是一個函數指針,那麼*pf就是該指針所指向的函數,是以(*pf)()就是調用該函數
- ANSI C标準允許程式員将(*pf)()簡寫為pf(),但是一定要記住這種寫法是一種簡寫形式
示範案例
- bool lengthCompare(const string&, const string&);
- bool (*pf)(const string&, const string&);
- int main()
- {
- pf = lengthCompare;
- bool b1 = (*pf)("hello", "goodbye");//相當于在調用lengthCompare("hello","goodbye")
- bool b2 = pf("hello","goodbye"); //同上,但是注意這是簡寫形式
- return 0;
- }
四、函數指針的注意事項
- 函數指針可以指派為空或者0
- 函數指針必須指向與指針傳回值類型以及參數相同的函數
五、重載函數的指針
- 定義一個重載函數指針時,必須有相對應比對的重載函數與指針比對
- void ff(int*);
- void ff(unsigned int);
- void (*pf)(int*)=ff; //正确,指向void ff(int*);
- void (*pf2)(int)=ff; //錯誤,沒有比對的函數
- double (*pf3)(unsigned in)=ff; //錯誤,沒有比對的函數
六、函數/函數指針傳參
- 一個函數的形參為函數或者函數指針時,調用這個函數時,函數形參可以為函數本身也可以為函數指針(調用時本質上傳入的都是函數的指針)
- bool lengthCompare(const string&, const string&);
- void useBigger(const string&, const string&, bool pf(const string&, const string&));
- void useBigger2(const string&, const string&, bool (*pf)(const string&, const string&));
- int main()
- {
- bool (*pf)(const string&, const string&);
- pf = lengthCompare;
- useBigger("hello", "goodbye",lengthCompare);
- useBigger("hello", "goodbye", pf);
- useBigger2("hello", "goodbye", lengthCompare);
- useBigger2("hello", "goodbye", pf);
- return 0;
- }
七、函數與函數指針取别名
- 可以使用typedef和decltype來簡化函數或函數指針的聲明
- 注意:decltype傳回的是函數類型,而不是指針類型,是以Funcp2前面還需要加上*
bool lengthCompare(const string&, const string&);
//Func和Func2都是函數類型
typedef bool Func(const string&, const string&);
typedef decltype(lengthCompare) Func2;
//FuncP和FuncP2都是函數指針類型
typedef bool(*FuncP)(const string&, const string&);
typedef decltype(lengthCompare) *FuncP2;
void useBigger(const string&, const string&, Func);
void useBigger2(const string&, const string&, FuncP);
int main()
{
bool (*pf)(const string&, const string&);
pf = lengthCompare;
useBigger("hello", "goodbye",lengthCompare);
useBigger("hello", "goodbye", pf);
useBigger2("hello", "goodbye", lengthCompare);
useBigger2("hello", "goodbye", pf);
return 0;
}
八、傳回函數的指針
- 函數和數組一樣不能直接通過傳回值傳回,而需要通過指針傳回
格式一:
- 下面是原始的定義方法,比較繁瑣
- 意義為:f1函數的參數為int,傳回值為函數指針類型,該函數指針指向的函數傳回值為int,參數為int*和int
int (*f1(int))(int*, int); 格式二:
- using F = int(int*, int); //F為函數類型
- using PF = int(*)(int*, int);//PF為函數指針類型
- PF f1(int); //f1函數傳回一個函數指針,該指針指向的函數傳回值為int,參數為int*和int
- F* f1(int); //同上
- F f1(int); //錯誤,F為函數類型,不能直接傳回
格式三:
auto f1(int)->int(*)(int*, int);
九、将auto和decltype用于函數與函數指針類型
- 将我們知道一個函數的傳回值為某種函數指針類型時,可以使用decltype簡化書寫
示範案例
- 例如下面的getFcn函數傳回值為sumLength函數指針類型,則可以使用下面的方法
- 注意:decltype傳回的是函數類型,是以還需要加上指針
- string::size_type sumLength(const string&, const string&);
- string::size_type largerLength(const string&, const string&);
- decltype(sumLength) *getFcn();