欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

函数指针读书笔记

发布时间:2024/1/17 编程问答 31 豆豆
生活随笔 收集整理的这篇文章主要介绍了 函数指针读书笔记 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
  • 函数指针的定义格式
  • <返回类型> (*<指针变量>)(<形参表>)   例如:
  •  

    int f(int); int (*pf)(int) = &f;

     

      pf是一个函数指针,它能够指向的是参数为int类型并且返回值为int类型的函数

      2.  也可以用typedef为函数指针类型取一个名字,然后再用该函数指针类型来定义指针变量:

          typedef  <返回类型>  (*<函数指针类型名>)(<形参表>)。

     

    typedef double (*PF)(double); PF pf;

     

      第一行是对一个函数指针进行了定义声明,声明了一个具有double返回值,并且参数是double类型的函数指针。以后就可以用PF来声明其它的相同类型的函数指针。

    • 函数指针的用途
      • 转换表(jump table)
      • 作为参数传递给另一个函数

     

           作为参数传递给另一个函数   用法主要是回调函数(callback function),也就是用户把一个函数指针作为参数传递给其它函数,后者将“回调”用户的函数。一个很常用的例子就是c函数库的qsort函数, qsort并不知道进行比较的值的类型,这是我们就可以传入一个比较函数的函数指针,对于不同类型的比较,我们可以让这个函数指针绑定到不同的函数上。这里就不详细说了。

        转换表  对于用户的不同输入,我们要调用不同的函数实现不同的功能,这时候也许我们可以用switch语句来实现。但是当每次我要增加一些操作的时候,就必须修改switch,也就是修改main函数里面的代码,这样是非常不方便的。那我们就可以用跳转表来实现,跳转表其实就是一函数指针数组。一般的用法如下[1]:

      

      代码实现如下:

    #include <stdio.h>typedef void (*PF)(void);struct jump_table{char ch;PF pf; };void pf_a(void) { printf("CALL pf_a\n"); } void pf_b(void) { printf("CALL pf_b\n"); } void pf_w(void) { printf("CALL pf_w\n"); }struct jump_table table[100] = { //跳转表{'a',pf_a},{'b',pf_b},{'w',pf_w},{0,NULL} };int main() {char ch;int i;while( (ch = getchar()) != 'x'){i = 0;while ((table[i].ch != 0)){if (ch == table[i].ch){ table[i].pf();break;}i++;}} }2013/10/16 22:33

      我们可以看到用户输入的key值是不连续的,所以我们必须每次都扫描一遍数组,同时我们在定义数组的时候要设置结束标志,这样能方便判断结束。

      但是如果用户输入的是从零开始的连续整数,或者是一些诸如连续字符a-z之类的,那么我们就可以直接跳转到相应的项,而不需扫描数组。比如我们在做计算器的时候,我们把ADD定义为0,SUB定义为1....[2],那么就可以如下的定义:

    double add(double, double); double sub(double, double); double mul(double, double); double div(double, double); ....double (*oper_func[])(double,double) = {add,sub,mul,div,..... };

      

    然后通过下面来调用相应的操作函数,oper为输入的值:

    result = oper_func[oper](op1, op2);

    oper_func从数组中选择正确的函数指针,而函数调用操作符将执行这个函数。当然,我们这里还需要的注意的是数组越界问题,为了保证所使用的下标位于合法的范围内,在一开始的时候我们可以先检查下标的合法性,然后再进行调用操作。

    •  参考资料
      •   [1] 我们老师上课的课件,具体解释权归老师所以;
      •       [2] 《C和指针》

     

    复杂函数指针的应用

      来看下下面这个代码:

    void (* pf(void (*fun)()))()

      咋第一眼看上去有点头晕呢!那么多括号,那么多嵌套。莫急莫急!我们来把它细分一下,首先看 void (*fun)(),这就是我们前面看到的函数指针,这个没问题。然后再看看

    pf(void (*fun)()),pf不也是一个函数嘛,只不过它的参数是一个函数指针罢了。那么如果我们令pf(void (*fun)())为X,那么那一整个式子可以表示成:void(*X)(),这就是函数指针的定义。说明X又是一个函数指针,也就是说函数pf的返回值又是一个函数指针。这样就都清楚啦,再来屡一下:pf这样一个函数:接受参数为函数指针,而且pf的返回值也是个参数为void返回值为void的函数指针。

    而且我们还可以用下面这两个定义来表示上面这个函数定义,这样看起来就明了多了:

     

    typedef void (*PF)(); PF pf(PF fun); typedef void PF(); PF *pf(PF *fun);

     从下面这个定义方式,我们就可以很明确的看到pf函数的参数是一个PF*类型,返回值也是一个PF*类型的函数。


     

    下面用一个程序来看看这个应用的例子:

     

    #include <stdio.h>void fun_a(int a,int b) {printf("This is function A.\n"); }void fun_b(int a) {printf("This is function B.\n"); }void (*pf(void (*fun)(int,int)))(int) {void (*p)(int);printf("This is function pf.\n");fun(1,1);p = fun_b;return p; }int main() {pf(fun_a)(1);return 0; }

    输出结果是:

     

     参考资料:

    http://bbs.csdn.net/topics/30344321

     

    转载于:https://www.cnblogs.com/Jason-Damon/p/3373101.html

    总结

    以上是生活随笔为你收集整理的函数指针读书笔记的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。