c语言|C语言问题集——指针进阶(2)

一、函数指针
先来看一段代码:

#include int ADD(int x, int y) { return x + y; } int main() { int a = 2; int b = 3; ADD(a, b); printf("%p\n", &ADD); printf("%p\n", ADD); return 0; }

c语言|C语言问题集——指针进阶(2)
文章图片

可以看出,函数也是有地址的,而且函数名和&函数名都是可以直接拿到函数本身的地址的
那么用来接收函数地址的指针变量是函数指针变量。
上图中的ADD函数因为其参数为int,int返回类型为int,所以用来接收ADD函数地址的指针变量(假设为pADD)就是(int)(*pADD)(int,int)。函数名是PADD,前面的*表示其是一个指针,后面的括号里的两个int是函数的参数类型,前面括号里的int是函数的返回类型。以此类推其他函数指针变量的写法。
我们可以看到,函数名和&函数名都是函数的地址。
void (*signal(int , void(*)(int)))(int)
分析一下这段代码:signal首先和括号结合,说明signal是一个函数,参数是int和一个参数为int,返回类型为void的函数指针,signal函数的返回类型是一个参数为int,返回类型为void的函数指针。
二、函数指针数组
首先,函数指针数组是一个数组,其中每个元素类型是函数指针。
例如我们已经写好了加减乘除的函数假设参数(2个)和返回类型都是int,函数名分别为ADD、SUB、MUL、DIV。那么我们就可以将其放入一个函数指针数组中。
函数指针数组就可以写为:int(*p[4])(int, int),由符号优先级知,p先和后面的方块结合,表示p是一个数组,然后去掉p[4]后就是数组里每个元素的类型,是一个函数指针,所以p就是一个函数指针数组。
三、回调函数
概念:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个
函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数
的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进
行响应。
下面看这样一段代码:
#include void Caculate(int(*p)(int, int)) { int result = (*p)(2, 3); printf("%d\n", result); } int ADD(int x, int y) { return x + y; } int main() { Caculate(ADD); }

像这样,ADD就是一个回调函数,因为它是通过函数指针在Caculate函数里调用的
。当然,具体的使用场景是按需要自己来规定的,比如减少代码冗余,用函数指针数组的时候可以考虑回调函数,另外,在库函数qsort里自己写的比较函数也是一个回调函数。
水平有限,欢迎指正。




【c语言|C语言问题集——指针进阶(2)】

    推荐阅读