经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
C/C++函数指针深入探究
来源:jb51  时间:2022/8/22 14:54:36  对本文有异议

函数指针

为什么要使用函数指针?

  • 调用的灵活性和通用性。

试想一下,我们在设计初期并不知道我们的函数的具体实现细节。例如,我们我们想要一个排序函数qsort,但是具体排序法则我们并不确定,是降序还是升序,采用什么算法都不清楚。这些问题是要在用户调用这个函数的时候才能够决定。于是调用者应该自己设计comparator函数,传给qsort函数。

  • 便于面向对象编程。

例如我们设计一个结构体apple。我们除了设计出苹果的属性比如,数量、重量、颜色外,我们还要定义关于苹果的操作,比如,吃掉,种植,这时候我们可以使用函数指针。然后我们以后调用这个结构体的时候,可以采用a.eat(&b)的方式调用函数。

  1. typedef struct apple{
  2. int number;
  3. double weight;
  4. colorType color;
  5. //some operations
  6. bool (*eat)(struct apple*);
  7. bool (*plant)(struct apple*);
  8. }apple;

语法

函数地址

函数的地址实际上就是函数名。这一点可以类比于数组。

声明

要声明指向特定类型的函数的指针,可以先编写这种函数的原型,然后用(*pf)代替函数名。或者采用C++11 的auto也能声明并初始化函数指针。

  1. double pam (int);
  2. //这是函数原型
  3. double (*pf)(int);
  4. //这是函数指针
  5. auto pn=pam;
  6. //定义并初始化函数指针

使用函数指针调用函数

  1. double pam (int);
  2. //这是函数原型
  3. double (*pf)(int);
  4. //这是函数指针
  5. auto pn=pam;
  6. //定义并初始化函数指针
  7. pf=pam;
  8. pam(4);
  9. (*pf)(4);
  10. (*pn)(4);

直接把函数地址(即函数名)赋值给函数指针就行了,注意特征标和返回类型必须相同。然后采用(*pf)(4)这样的方式调用函数。实际上,C++也允许这样子使用函数指针:

  1. pf(4);//这种形式好看且实用,但是没有显示出 使用函数指针调用函数
  2. pn(4);

深入理解函数指针

阅读这一篇幅,需要您熟练掌握,C语言中的指针

  1. //一些函数原型
  2. const double* f1(const double ar[],int n);
  3. const double* f2(const double *,int);
  4. const double* f3(const double *,int);
  5. //函数指针
  6. const double* (*p1)(const double ar[],int n)=f1;
  7. auto p2=f2;//感谢auto
  8. //调用函数
  9. cout<<(*p1)(av,3)<<*(*p1)(av,3);
  10. cout<<p2(av,3)<<*p2(av,3);
  11. //实际上 *p2(av,3)和*(*p2)(av,3)是一样的。不理解的看上面内容。
  12. //包含3个函数指针的数组
  13. const double* (*pa[3])(const double *,int)={f1,f2,f3};
  14. //注意:
  15. //1、[]优先级高于* 所以这是个数组不是指针。
  16. //2、不能使用auto定义并初始化列表
  17. auto pb=pa;
  18. //既然已经声明了数组,数组名就是指针,采用auto可以定义初始化指针,这是合法的。
  19. //调用函数
  20. double x=*pa[0](av,3);
  21. double y=*(*pb[1])(av,3);//由于[]优先级高于* 所以pb[1]是个函数指针。然后(*pb[1])就是调用函数了。
  22. //更加深入
  23. const double *(*(*pd)[3])(const double *,int) = &pa;
  24. //首先把函数指针的壳子去掉即 const double *(* ···)(const double *,int),然后得到(*pd)[3]这里 pd先和* 结合 再和[]结合,所以pd是个指针,这个指针指向一个数组,这个数组的元素又是函数指针。
  25. //是不是特别绕?
  26. //感谢auto
  27. auto pc=&pa;
  28. //调用
  29. (*pd)[0](av,3);
  30. //pd是指向数组的指针,则(*pd)[0]就是数组的元素,数组的元素是函数指针,所以可以采用这种方式调用函数。
  31. //或者采用 (*(*pd)[0])(av,3)调用函数也是等价的。
  32. double z=*(*pd)[0](av,3);
  33. //或者 采用 double z=*(*(*pd)[0])(av,3) 也是等价的

我们对于语法的了解不能仅仅潜于认识,对于这种const double *(*(*pd)[3])(const double *,int) = &pa; 我们不光要认识,更要会使用,再次重温一遍,我们想要一个指向数组的指针,这个数组里的元素是函数指针。

第一步,数组元素的类型是函数指针,所以壳子要有 const double *(* ···)(const double *,int)

第二步,指向数组的指针 (*pd)[3] ,由于[]比*优先级高,所以我们必须采用(),否则 *pd[3] 就是一个数组,数组的元素是指针。 第三步,结合得 const double *(*(*pd)[3])(const double *,int) = &pa

使用typedef 简化

  1. typedef const double *(* p_fun)(const double *,int);
  2. p_fun p1=f1;
  3. p_fun pa[3]={f1,f2,f3};
  4. p_fun (*pd)[3]=&pa;

typedef 使得代码量减少很多,而且更容易理解

到此这篇关于C/C++函数指针深入探究的文章就介绍到这了,更多相关C++函数指针内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号