本节主要对函数类指针做讲解,并且对于写通讯录和简单计算器有一定参考意义。
#1.函数指针
顾名思义,函数指针就是指向函数的指针,具体用法看代码
#include <stdio.h> int Add(int x, int y) { return x + y; } int main() { int (*p1)(int, int) = Add; int (*p2)(int, int) = &Add; int a1 = p1(1, 2); int b1 = (*p1)(1, 2); int a2 = p2(1, 2); int b2 = (*p2)(1, 2); printf("%d %d %d %d", a1, b1, a2, b2); //int c = *p(1, 2); //error return 0; }
int (*p)(int,int)中*p表示p是一个指针,他指向的函数类型为int (int,int),所以其实函数名就是个地址,在后面的函数栈帧里我们将会清晰地看到,而上面代码的显示结果表明&函数名与函数名得出的结果是相同的,所以这两种都是可以的,但在解引用时要给让指针加上括号再解引用,不然指针就会与括号结合了。
#2.函数指针数组
函数指针数组,就是个数组,他的每一个元素都是函数指针,用法看举例:
#include <stdio.h> int Add(int x, int y); int Mul(int x, int y); int Div(int x, int y); int Sub(int x, int y); int main() { int input = 0; int (*p[5]) (int, int) = {NULL,Add,Sub,Mul,Div}; do { scanf("%d", &input); switch (input) { case 0: break; case 1: p[1](3, 4); break; case 2: p[2](3, 4); break; case 3: p[3](3, 4); break; case 4: p[4](3, 4); break; default: break; } } while (input); return 0; } int Add(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 Sub(int x, int y) { return x + y; }
我们可以对比一下:
int (*p) (int,int)
int (*p[5]) (int,int) 由于[]的优先级高于*,所以p先与[]结合表明p[5]是个数组,则数组的每个元素的类型就是int (*) (int,int).
#3.指向函数指针数组的指针
还是先用指向整型指针数组的指针进行类比;
int main() { int a = 0; int b = 0; int* arr[5] = { &a,&b }; //指向整型指针数组的指针parr int* (*parr)[5] = &arr; int (*fun[5])(int, int) = { NULL,Add,Sub,Mul,Div }; //指向函数指针数组的指针pfun int (*(*pfun)[5])(int,int) = &fun; return 0; }
int (*(*pfun)[5]) (int,int)中,*pfun表明pfun是一个指针,指向的类型为int (*[5]) (int,int)这样的一个类型
#4.回调函数
回调函数就是如果你把函数的指针(地址,函数名就是其地址)当做参数传递给另一个函数,当这个指针被调用其所指向的函数时,我们就说这是回调函数。
如我们接下来所举例的Caculate函数,其他四个函数分别作他的参数,在他的函数内部被调用,我们就说Caculate是回调函数.
上面函数指针数组的代码还可以用回调函数做出改进:
#include <stdio.h> int Add(int x, int y); int Mul(int x, int y); int Div(int x, int y); int Sub(int x, int y); void Cauculate(int (*p)(int, int)) { int x = 0; int y = 0; printf("please input two number:\n"); scanf("%d %d", &x, &y); printf("%d\n", p(x, y)); } int main() { int input = 0; do { scanf("%d", &input); switch (input) { case 0: break; case 1: Cauculate(Add); break; case 2: Cauculate(Sub); break; case 3: Cauculate(Mul); break; case 4: Cauculate(Div); break; default: break; } } while (input); return 0; } int Add(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 Sub(int x, int y) { return x + y; }