函數指針:指向函數的指針變量,在C編譯時,每一個函數都有一個入口地址,那么指向這個函數的函數指針便是指向這個地址。函數指針主要有兩個作用:用作調用函數和做函數的參數。
int (*func)(int x);
諸如上面的代碼這是申明了一個函數指針,代碼(*func)中括號是必須的,這會告訴編譯器這是一個函數指針而不是聲明一個具有返回類型為指針的函數,后面的形參要是這個函數所指向的函數形參而定。使用如下面的代碼:
#include <iostream>
using namespace std;
int(*func)(int a, int b);
int bar(int a, int b)
{
return a + b;
}
int foo(int a, int b)
{
return a;
}
int main()
{
func = bar;
cout << func(12, 34) << endl;
system("pause");
func = foo;
cout << func(12, 34) << endl;
system("pause");
return 0;
}
這樣的聲明有些繁瑣,其實可以使用typedef來進行簡化:
#include <iostream>
using namespace std;
typedef int(*PF)(int, int);
//int(*func)(int a, int b);
int bar(int a, int b)
{
return a + b;
}
int foo(int a, int b)
{
return a;
}
int main()
{
PF func;
func = bar;
cout << func(12, 34) << endl;
system("pause");
func = foo;
cout << func(12, 34) << endl;
system("pause");
return 0;
}
函數指針的另一個作用就是作為函數的參數,可以在一個函數的形參列表中傳入函數指針,然后邊可以在這個函數中使用這個函數指針所指向的函數,這樣邊可以使程序變得更加清晰和簡潔。
#include <iostream>
using namespace std;
typedef int(*PF)(int, int);
//int(*func)(int a, int b);
int bar(int a, int b)
{
return a + b;
}
int foo(int a, int b)
{
return a;
}
void func(int a, int b, PF ptr)
{
cout << ptr(a, b) << endl;
return;
}
int main()
{
PF ptr;
ptr = bar;
func(12, 34, ptr);
system("pause");
ptr = foo;
func(12, 34, ptr);
system("pause");
return 0;
}
一旦知道函數指針是如何工作的,我們就可以構建一些復雜的定義,例如:
void *(*(*fp1)(int))[10];
fp1是一個指向函數的指針,該函數接受一個整型參數,並且返回類型是一個指向包含了10個void指針數組的指針。是不是很繞?
float (*((*fp2)(int,int,float)))(int);
fp2是一個指向函數的指針,該函數接受三個參數(int,int,float),返回值是一個指向函數的指針,該函數接受一個整型參數並返回一個float。
typedef doubele (*(*(*fp3)())[10])();
fp3是一個函數指針,該函數無參數,且返回一個指向含有10個指向函數指針指針數組的指針,這些函數不接收參數,且返回值是double值
int (*(*fp4())[10])();
fp4是一個返回指針的函數,該指針指向含有10個函數指針的數組,這些函數的返回值是整型。
指針函數
與函數指針相區別的定義應該就是指針函數,指針函數本質上是一個函數,是指函數的返回值為指針的函數,一般是形如下的函數:
int* func(int x,int y);
如上就是一個返回值是指針的函數,很常見。
函數對象
上面談到了函數指針以及應用,這里涉獵下函數對象。從一般函數回調意義上來說,函數對象和函數指針是相同的,但是函數對象卻具有許多函數指針不具有的優點,函數對象使程序設計更加靈活,而且能夠實現函數的內聯(inline)調用,使整個程序實現性能加速。
