1.知识点
(1)指针可以指向任何类型,也可以指向函数。每个函数在内存中都占用一段存储单元,这段存储单元的首地址称为函数的入口地址,指向之歌函数入口地址的指针称为函数指针。
(2)函数基本用法如下:
1 int max(int a, int b) { 2 return a > b ? a : b; 3 } 4 int (*p)(int, int) = max;//定义函数指针时必须指明函数返回的类型和参数列表 5 int x = 10, y = 20; 6 int z = p(x, y);//可以直接把函数指针当做函数名来用,也可以用int z=(*p)(x,y);
注意:(2.1)函数名等价于函数的入口地址;(2.2)定义函数指针时()不能少,如果少了int *p(int,int)变成是一个函数,返回值是int *的函数,而不是指针了;(2.3)函数指针的类型务必要和函数的返回值以及参数列表都要匹配。
2.面试题
2.1通过函数指针实现四则运算
指出下面程序的不足,并提出更好的设计方案。
1 int add(int a, int b) { 2 return a + b; 3 } 4 int minu(int a, int b) { 5 return a - b; 6 } 7 int multi(int a, int b) { 8 return a * b; 9 } 10 int process(int a, int b, char operation) { 11 switch (operation) 12 { 13 case '+':return add(a, b); 14 case '-':return minu(a, b); 15 case '*':return multi(a, b); 16 default: 17 return 0; 18 } 19 } 20 int main(int argc, char argv[]) { 21 int a = 10, b = 20; 22 int res1 = process(a, b, '+'); 23 int res2 = process(a, b, '-'); 24 int res3 = process(a, b, '*'); 25 cout << res1 << " " << res2 << " " << res3 << endl; 26 27 getchar(); 28 return 0; 29 }
问题:扩展性很差,比如需要添加一个除法运算,这时不仅需要编写除法运算函数,还要去修改process函数,添加除法的判断分支。解决办法:可通过函数指针来提高扩展性(由于此处加减乘除的返回值和参数列表都是相同的),具体方式如下:
1 int add(int a, int b) { 2 return a + b; 3 } 4 int minu(int a, int b) { 5 return a - b; 6 } 7 int multi(int a, int b) { 8 return a * b; 9 } 10 int divide(int a, int b) { 11 if (b == 0) { 12 return -1; 13 } 14 return a / b; 15 } 16 17 int process1(int a, int b, int(*func)(int, int)) { 18 return func(a, b); 19 } 20 int main(int argc, char argv[]) { 21 int a = 10, b = 20; 22 int res1 = process1(a, b, add); 23 int res2 = process1(a, b, minu); 24 int res3 = process1(a, b, multi); 25 int res4 = process1(a, b, divide); 26 cout << res1 << " " << res2 << " " << res3 << " " << res4 << endl; 27 getchar(); 28 return 0; 29 }
2.2简化超长的函数指针类型
请解释process函数中四个参数的作用,其中第四个参数int (* fun) (int,int,int)似乎不太美观,有什么办法让它看起来更加简洁?
1 int maxof3(int a,int b,int c); 2 int minof3(int a,int b,int c); 3 int avgof3(int a,int b,int c); 4 int process(int a,int b,int c,int (*func)(int,int,int)){return func(a,b,c);}
答案:前三个是整型变量,第四个是函数指针;使用typedef来给类型起别名,用法如下:
1 typedef int(* Pfunc)(int ,int, int);//使用Pfunc来指代int (*)(int,int,int) 2 int process(int a,int b,int c,Pfunc func);