携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
6. 函数指针
引例:
int add(int x,int y)
{
return x + y;
}
int main()
{
&add;
return 0;
}
对于函数的地址应该怎么储存呢?那就需要用函数指针类型进行接收。 对于上面的代码,我们可以这样写
int (*p)(int,int)对于上面这个可以这么理解: ==*== 告诉我们P是个指针,从后面的小括号可以看出是个函数,函数的参数有两个,都是int 类型的,返回类型是int
下面这样进行使用:
int(*p)(int,int)=&add;
(*p)(1, 2);
(**p)(1, 2);
p(1, 2);
add(1, 2);
我们发现上面这3种都正确,说明p变量前面的星号没有任何用处,p就相当与add。
看下面的这个代码可以更好的理解:我们发现打印的结果相同
printf("%p\n",add);
printf("%p\n", &add);
- 看着两个表示的是什么:
(*(void (*)())0)()void (*signal(int , void(*)(int)))(int)我们一点一点拆分看
(*(void (*)())0)();
1.void (*)()这是一个函数指针类型,无参数,返回类型为空(void)
2.(void (*)())0这个是强制类型转换,把0强转为函数指针类型
3.*解引用变成函数,调用函数,函数无参数
void (*signal(int , void(*)(int)))(int);
1.void(*)(int)这是一个函数指针类型,返回类型为空,参数为int类型的
2.signal(int , void(*)(int))这是一个函数,函数名为signal,
参数有俩个,分别为int类型和函数指针类型。
3.函数要有返回类型,去掉signal(int , void(*)(int)),就是该函数的返回类型
该函数的类型为void (*)(int),函数指针类型。
对这个函数可以进行一下好看的改变
typedef void (*v_i)(int)
然后这样写:v_i signal(int,v_i);这样看着是不是非常舒服
7. 函数指针数组
函数指针数组 是个数组,里面的元素是是函数指针
给个例子:
void f1()
{}
void f2()
{}
int main()
{
void (*p[2])()={f1,f2};
这个就是函数指针数组,
这样理解p先和[]结合说明p是一个数组,数组有2个元素,
每个元素的个数是void (*)()函数指针类型
return 0;
}
8. 指向函数指针数组的指针
指向函数指针数组的指针 它是一个指针,指向一个数组,数组的每个元素是函数指针类型
看下面的这个代码:
void f1()
{}
void f2()
{}
int main()
{
void (*p[2])()={f1,f2};
void(*(*p1)[2])()=&p;
p1就是一个函数指针数组的指针
return 0;
}
9. 回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。 回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
下面有个例子:
void f1()
{}
f(int a,void (*p)())
{
p();
}
int main()
{
int a;
f(a, f1);
把f1函数作为参数传给f函数,通过函数指针来调用f1函数。
return 0;
}
10. 小型计算器项目(对7,8,9等知识点的运用)
#include <stdio.h>
int add(int x, int y)
{
return x + y;
}
int sub(int x, int y)
{
return x - y;
}
int mul(int x, int y)
{
return x * y;
}
int div(int x, int y)
{
return x / y;
}
void menu()
{
printf("**** 请选择 ****\n");
printf("**** 1.加 2.减 **********\n");
printf("**** 3.乘 4.除 **********\n");
printf("************* 0退出 ***************\n");
}
f(int (*p)(int, int))
{
int a, b;
printf("请输入两个整数:>");
scanf("%d%d", &a, &b);
printf("结果为%d\n", p(a, b));
}
int main()
{
int n;
int (*gather[5])(int, int) = { 0,add,sub,mul,div };
该函数指针数组里面存的是各个函数的地址,首个元素设置为0,
方便用下标访问
do
{
menu();
该函数打印菜单,供用户选择
scanf("%d", &n);
if (n == 0)
{
printf("退出程序\n");
}
else if (n > 0 && n < 5)
{
f(gather[n]);
这就是一个回调函数
}
else
{
printf("选择错误请从新选择\n");
}
} while (n);
return 0;
}
运行的基本情况如下: