一.函数指针
首先看一段代码
#include<stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
}
输出的是两个地址,这两个地址是test函数的地址,那我们的函数地址想要保存起来,怎么保存?
首先,能够存储地址,就需要一个指向函数的指针变量,即函数指针
void (*fun1)();
fun1先与指针结合,说明fun1是指针,指针指向的函数无参数,返回值类型为void
下面看两段有趣的代码
(*(void(*)())0)()
把0强制转换成void(*)()类型的函数指针,0就是一个函数的地址,解引用后调用0地址处的函数
void (*signal(int ,void(*)(int)))(int)
首先signal是一个函数声明,函数有两个参数,一个是整型,一个函数指针类型
函数的返回值类型是将函数名以及参数去掉,剩下的就是返回值类型,该函数的返回值类型也是一个函数指针类型
这段代码有些复杂,我们可以将其简化
typedef void(* pfun_t)(int);
pfun_t signal(int ,pfun_t);
函数指针的使用
#include<stdio.h>
int add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 10;
int b = 20;
int(*pa)(int, int) = add;
printf("%d\n", pa(2, 3));
printf("%d\n", (*pa)(2, 3));
}
二.函数指针数组
我们已经学习过了指针数组,比如int*arr[10] .
如果把一个函数的地址存到数组里,这个数组就叫做函数指针数组,定义方式如下:
int(*pa[10])(int ,int);
pa先与[]结合,说明pa是个数组,数组的内容是什么呢?是int(*)(int ,int)类型的函数指针
思考:
char*my_strcpy(char*dest,const char*src);
1 . 写一个函数指针,能够指向my_strcpy
2 . 写一个函数指针数组,能够存放4个my_strcpy函数的地址
char*(*p)(char* ,const char*);
char*(*p[4])(char* ,const char*);
函数指针数组用途:转移表
例:计算器
#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;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int, int) = {
0,add,sub,mul,div };
while (input)
{
printf("*******************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf("*******************************\n");
printf("请选择:");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
printf("请输入操作数:");
scanf("%d %d", &x, &y);
ret = p[input](x, y);
}
else
printf("输入有误\n");
printf("ret=%d\n", ret);
}
}
未完待续…