zoukankan      html  css  js  c++  java
  • (C/C++学习)16.函数指针

    说明:函数指针,顾名思义就是指向函数的指针。C/C++中函数名的本质其实就是一段代码段空间的首地址。

    1.定义

    如下的 pf 就是一个函数指针,指向所有返回类型为 int,并带有两个 const int 参数的函数。需要注意的是 *pf 两边的括号不能少,否则下面定义就变成声明一个函数 pf其返回类型为 int *, 带有两个 const int 参数。

      1 int (*pf)(const int, const int);

     

    2.取别名

    如果每次都像上面那样来声明一个函数指针,那样就显得太复杂了,我们可以通过取别名的方式来简化声明复杂程度,如下:

      1 typedef int (*cmpFun)(const int, const int);

    这样,cmpFun 就成了一种数据类型,可以用它来声明和定义形如上面 pf 那样的函数指针,比如:

      1 cmpFun pf = someFunction;
      2 cmpFun pf = &someFunction;

    下面是一个测试代码:

      1 #include <stdio.h>
      2 
      3 void myCmp(int a,int b)
      4 {
      5     printf("%d	%d
    ",a,b);
      6 }
      7 
      8 typedef void (*PF)(int a, int b);
      9 PF pf = myCmp;
     10 
     11 int main(void)
     12 {
     13     (*pf)(1,2);
     14     pf(1,2);
     15     //两种访问方式都没问题
     16     return 0;
     17 }

     

    3.函数名作为地址的用法

    上面提到了,函数名的本质是一个地址,那如果我们拿到这个地址,是否可以直接调用相应的函数呢?答案是肯定的!如下代码,先打印出函数名所代表的地址,然后将其强转成 PF 函数指针类型,然后在对其进行函数的调用。

      1 #include <stdio.h>
      2 
      3 void myCmp(int a,int b)
      4 {
      5     printf("%d	%d
    ",a,b);
      6 }
      7 
      8 typedef void (*PF)(int a, int b);
      9 PF pf = myCmp;
     10 
     11 int main(void)
     12 {
     13     pf(1,2);
     14     printf("%p	%p
    ",myCmp,&myCmp);
     15    ((PF)(0x00401610))(1,2);
     16     return 0;
     17 }

    上面代码的打印结果为:

      1 1       2
      2 00401610        00401610
      3 1       2

     

    4.回调函数

    当函数作为参数而发起的调用函数的过程,就叫作函数的回调。函数的回调其实也是利用了函数指针这一概念。下面是一个回调示例:

      1 #include <stdio.h>
      2 
      3 void myCmp(int a,int b)
      4 {
      5     printf("%d	%d
    ",a,b);
      6 }
      7 void prin(void (*p)(int a,int b))
      8 {
      9     p(1,2);
     10 }
     11 
     12 int main(void)
     13 {
     14     prin(myCmp);
     15     return 0;
     16 }

    5.函数指针数组

    如下定义一个返回值和参数皆为 void 的函数指针数组:

      1 void (*funcArray[N])(void);

    函数指针的一个用法出现在菜单驱动系统中。例如程序可以提示用户输入一个整数值来选择菜单中的一个选项。用户的选择可以做函数指针数组的下标,而数组中的指针可以用来调用函数。下面是一个程序示例:

      1 #include <stdio.h>
      2 void func1()
      3 {
      4     printf("void func1()
    ");
      5 }
      6 void func2()
      7 {
      8     printf("void func2()
    ");
      9 }
     10 void func3()
     11 {
     12     printf("void func3()
    ");
     13 }
     14 
     15 int main(void)
     16 {
     17     int i = 0;
     18     void (*p[3])(void) = {func1,func2,func3};
     19     for(;i<3;i++)
     20         (p[i])();
     21     return 0;
     22 }
     23 
     24 

    6.拓展

      1 (*(void(*) ()) 0)()

    思考以上代码的意义!

  • 相关阅读:
    资深项目经理推荐的几款免费/开源项目管理工具
    内网穿透工具frp简单使用教程
    10部全尺度欧美宫斗剧!献给不甘平淡的你
    Spring Boot后端+Vue前端+微信小程序,完整的开源解决方案!
    搭建Keepalived + Nginx + Tomcat的高可用负载均衡架构
    集成Activiti工作流的J2EE快速开发框架
    国内5大前端团队网站,你了解多少
    5 天 4000 star 的一个爆款开源项目
    「干货」常用的10个网络DOS命令,菜鸟学了变高手
    js自定义正则表达式
  • 原文地址:https://www.cnblogs.com/tuihou/p/9858395.html
Copyright © 2011-2022 走看看