zoukankan      html  css  js  c++  java
  • 如何解读返回函数指针的函数声明

    int (*(*pf())())() {
        return nullptr; 
    }

      从来没有见过这样的函数声明。那么它究竟是一个怎样的函数呢?我努力回忆起《C专家编程》一书的内容,把其中解读变量声明的方法应用于该函数上,最终读懂了该函数。下面是大致的解读过程。

      首先,要确定声明中出现的操作符的优先级。显然,函数调用操作符()的优先级是高于指针解引用操作符*的。另外,小括号总是具有最高优先级。

      其次,要确定在声明中标识符与某个操作符结合起来的时候有什么意义。例如:

      a()    a是一个函数
      *a     a是一个指针

      由于函数声明的特殊性,当指针解引用操作符*与一个表示函数的标识符结合时,表示这个函数的返回值是一个指针。例如 *a() 表示a是一个返回值为指针的函数。

      有了以上的基础,接下来我们就可以从声明中的标识符开始,按照操作符的优先级,由内向外逐步来解读:

                pf()            pf是一个无参数函数
              * pf()            pf是一个无参数函数,它的返回值是一个指针
            ( * pf() ) ()       pf是一个无参数函数,它的返回值是一个无参数函数的指针
          * ( * pf() ) ()       pf是一个无参数函数,它的返回值是一个无参数函数的指针,这个函数的返回值又是一个指针
        ( * ( * pf() ) () ) ()  pf是一个无参数函数,它的返回值是一个无参数函数的指针,这个函数的返回值又是一个无参数函数的指针
    int ( * ( * pf() ) () ) ()  pf是一个无参数函数,它的返回值是一个无参数函数的指针,这个函数的返回值又是一个无参数且返回值为int的函数的指针。

      

         最终的解读结果冗长拗口。可以看出,这实际上是返回值为函数指针的函数的递归声明。下面是可读性更强的等效代码:

    typedef int (*pa)(); 
    typedef pa (*pb)(); 
    pb pfex() {  
        return nullptr; 
    }

      下面是验证解读结果的测试代码。不得不说,测试代码也不容易理解……

    #include <iostream>
    
    int a() {
        return 29; 
    }
    
    int (*b())() {
        return a; 
    }
    
    int (*(*pf())())() {
        return b; 
    }
    
    typedef int (*pa)(); 
    typedef pa (*pb)(); 
    pb pfex() {  
        return b; 
    }
    
    int wmain() {
    
        int r = pf()()();  
        std::wcout << r << std::endl;
    
        r = pfex()()();  
        std::wcout << r << std::endl;  
    }
  • 相关阅读:
    【转】Windows2012设置文件夹权限报错:failed to enumerate objects in the container.
    Vue 中背景图片路径怎么加参数?
    C#有小数位数直接进位为整数;JavaScript Math有小数位数取整方法
    C# Linq to Entity使用Groupby查询时超时或很慢解决思路
    colModel的设置(给单元格指定颜色等)
    金额的表示方法
    jqGrid表格时间格式化 ,formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d H:i:s H:i:s'}
    HTTP Error 414. The request URL is too long. asp.net解决方案
    radio/checkbox各种操作
    Kubernetes常用命令总结
  • 原文地址:https://www.cnblogs.com/renyuan/p/6266376.html
Copyright © 2011-2022 走看看