复习C语言指针—函数指针
函数
一个函数表达式其实是不存在直接的"()"操作符的,“()”操作符要求操作数是函数指指针(或者一些类类型)。
实际上,当用 f1(); 这样调用f1时,f1是函数名,“()”会先 f1 转换成函数指针,然后再作为“()”在操作符的操作数完成函数的调用。
函数指针
先简单定义一个函数,比如
int Add(int x, int y)
{
return x + y;
}
这是一个实现两个相加的函数
而函数指针,就是指向这个函数的指针,可以通过解引用来调用这个函数
具体代码如下
(*p)表示是指针 (int,int)为指向函数的参数 int表示指向函数的返回类型
int(*p)(int, int) = &Add;
注意:函数名可以代表函数的地址
代码如下:
int(*p)(int, int) = &Add;
int(*p1)(int, int) = Add;
printf("%p\n", Add);
printf("%p\n", &Add);
结果如下:
同时
又值得注意的一点是,函数指针的解引用是可以重复进行的
先看现象
int(*p)(int, int) = &Add;
printf("%p\n", *p);
printf("%p\n", **p);
//每一次解引用,都会将*p再转换成p
//***p,经历3次解引用的隐式转换,又变成p了
printf("%p\n", ***p);
原理如下:
正如最开始所说,函数名本身并不能调用函数,是()操作符把函数名转换成函数指针,然后才能调用函数。
而*p也是通过解引用得到函数名,然后编译器再隐式转换成函数指针,然后变成p。以此类推,***p是通过3次解引用,又转换成p
接下来是通过函数指针调用函数,(函数还是Add)
代码如下:
int ret = (*p)(3, 5);
int ret1 = p(3, 5);
int ret2 = (*****p)(3, 5);
printf("%d\n", ret);
printf("%d\n", ret1);
printf("%d\n", ret2);
函数指针数组
将函数指针和指针数组结合
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int main()
{
int(*p1)(int, int) = Add;
int(*p2)(int, int) = Sub;
//函数指针数组
int(*ps1[2])(int, int) = { p1,p2 };
return 0;
}
回调函数
回调函数
a函数的参数是函数指针,传入其他函数的地址,用这个函数指针接收,并用函数指针调用
可以减少很多重复的代码
比如计算器,可以用calc(int(*ps)(int,int))这个函数接收四则运算的函数
结束语
文章如果有不对或者不足的地方,欢迎大佬们指正,补充。感谢大家的阅读,如果感觉博主写的还可以,麻烦点个赞支持一下,阿里嘎多。拜托了,这对我真的很重要~