指针函数和函数指针
函数指针:指向函数的指针变量,在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)调用,使整个程序实现性能加速。