函数指针:指向函数的指针
指针函数:函数的返回值为一个指针
首先应该明确以下这里说的函数指针实质上是一个指针,这个指针指向一个函数。指针怎么能够指向一个函数呢?那是因为函数也是存储在内存中的某个位置的,和其他数据类型一样,函数指针会返回指向存储该函数的内存的首地址。
说了这么多那么到底函数指针长什么样呢?先看一下一般的变量和指针长什么样:
定义一个整型的变量:int number = 0;
定义一个指向整型数据的指针:int *iPtr = &number;
现在假如我们的函数指针指向的函数张的这样子(关键是函数的形参列表!):
int add(int num1, int num2)
{ return num1 + num2);}
那么指向一个函数的指针就可以类似的定义如下了(注意这里(*pf)两边的圆括号千万不能省略,要不然就成返回值为int*的函数了):
int (*fp)(int, int) = add;
划重点了!因此把函数指针的格式定义如下:
函数的返回类型 (*函数指针的名字)(函数的形参1, 函数的形参2, ...);
说了这么多,下面总结一下函数指针在实际的应用场景怎么使用。在实际应用中函数指针可以作为普通的变量使用,可以作为形参使用,也可以作为返回指向函数的指针使用。
1、作为普通的变量使用
继续以上面的sum函数作为示例,定义一个函数指针fp,fp的值为函数sum的首地址,因此就可以以下面的方法使用函数指针:
fp(5, 6); // 这样写也可以,但是这样的程序不直观,读者会以为fp是一个函数。
(*fp)(5, 6); // 建议使用这样的方式
#include <stdio.h>
int sum(int num1, int num2)
{
return num1 + num2;
}
int main(int argc, char** argv) {
int (*fp)(int, int) = sum;
// 函数指针作为变量使用
printf("%d\n", (*fp)(5, 6));
return 0;
}
2、作为形参使用
顾名思义,就是在函数的参数中有个参数是函数指针,那么就可以在这个函数中调用这个函数指针。使用方法见代码:
#include <stdio.h>
int sum(int num1, int num2)
{
return num1 + num2;
}
int printResult(int (*fp)(int, int), int num1, int num2)
{
printf("%d\n", (*fp)(num1, num2));
}
int main(int argc, char** argv) {
// 函数指针作为参数使用
printResult(fp, 5, 6);
return 0;
}
3、作为函数的返回值使用
这种方法也是比较迷,很容易把读者绕进去,先看代码示例:
#include <stdio.h>
int sum(int num1, int num2)
{
return num1 + num2;
}
int printResult(int (*fp)(int, int), int num1, int num2)
{
printf("%d\n", (*fp)(num1, num2));
}
int (*returnResult())(int, int)
{
return sum;
}
int main(int argc, char** argv) {
// 函数指针作为返回值使用
int (*fp2)(int, int) = returnResult();
printf("%d\n", fp2(5, 6));
return 0;
}
在这段代码里,先定义了一个函数指针fp2,fp2接受的函数需要有两个整型的参数并且返回值也是一个整型。使用returnResult()函数给fp2赋值,那么returnResult()函数的返回值应该是一个函数指针。我们移步到returnResult()函数中看一看,发现这个函数返回的是sum,而sum是一个函数,因此这个函数返回的就是一个函数的首地址(也即指针)。
下面对函数指针作为函数返回值的使用方法做一个小小的说明,定义函数指针作为返回函数的函数写法需要重点关注一下。函数名和函数的参数写法和平时的函数写法无差别,但是需要在最前面加上*,并且用圆括号括起来,就像这样:
返回的函数的返回值的类型 (*函数名(函数形参列表))(返回的函数的形参列表);
看到这里是不是对函数指针的使用方法有了基本的认识了?