C语言 指针的理解 — 3

什么是函数指针?

和数组指针有些类似,指向函数的指针就是函数指针

其实函数也是有地址的:

int Add(int x, int y) { return x + y; } int main() { printf("%p\n", &Add); printf("%p\n", Add); return 0; }

这里的 &Add 和 Add 的效果是一样的,取出的都是函数的地址。

既然可以得到函数的地址那么函数也是存在的。

int(*pf)(int, int) = &Add;

左边的 int 表示函数的返回类型是 int,右边的(int ,int)是函数的参数的类型。

函数指针的书写形式是和函数返回类型以及函数的参数密切相关的

函数指针有什么用?

通过存放函数的地址,间接访问函数,和其他指针的作用是一样的。

int Add(int x, int y) { return x + y; } int main() { int(*pf)(int, int) = &Add; int ret = (*pf)(2, 3); printf("%d\n", ret); ret = pf(3, 4); printf("%d\n", ret); return 0; }

这个 * 可写可不写,效果相同。

下面是函数指针的应用场景:

void menu() { printf("**********************\n"); printf("*** 1.Add 2.Sub ****\n"); printf("*** 3.Mul 4.Div ****\n"); printf("*** 0.Exit ****\n"); printf("**********************\n"); } 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 input = 0; int x = 0; int y = 0; int ret = 0; do { menu(); printf("请输入>"); scanf("%d", &input); switch (input) { case 1: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Add(x, y); printf("%d\n", ret); break; case 2: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Sub(x, y); printf("%d\n", ret); break; case 3: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Mul(x, y); printf("%d\n", ret); break; case 4: printf("请输入2个数"); scanf("%d %d", &x, &y); ret = Div(x, y); printf("%d\n", ret); break; case 0: printf("退出\n"); break; default: printf("输入错误\n"); } } while (input); return 0; }

可以发现:进入case语句时代码是非常冗余的,如果想把调用算数的冗余代码,分装成一个函数,但又要做到实现不同的函数调用时,函数指针就会帮大忙。

把代码用函数指针写成这样,就会大大减少冗余度。这种方法其实是回调函数的使用

void calc(int pf(int , int )) { int x = 0; int y = 0; printf("请输入2个数"); scanf("%d %d", &x, &y); int ret = pf(x, y); printf("%d\n", ret); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; do { menu(); printf("请输入>"); scanf("%d", &input); switch (input) { case 1: calc(Add); break; case 2: calc(Sub); break; case 3: calc(Mul); break; case 4: calc(Div); break; case 0: printf("退出\n"); break; default: printf("输入错误\n"); } } while (input); return 0; }