【问题标题】:What is the meaning of the declaration "char (* ( *f())[])();"?声明“char (* ( *f())[])();”是什么意思?
【发布时间】:2014-08-13 10:28:03
【问题描述】:

当我发现这个声明时,我正在获取有关函数指针的信息:

char (* ( *f())[])();

我试图找出它的含义,但我无法...

它指的是什么?

【问题讨论】:

    标签: c arrays pointers function-pointers


    【解决方案1】:

    分解如下:

             f           -- f
             f()         -- is a function returning
            *f()         -- a pointer to
           (*f())[]      -- an array of
          *(*f())[]      -- pointer to
         (*(*f())[])()   -- function returning  
    char (*(*f())[])();  -- char
    

    [] 等后缀运算符和函数调用() 绑定在* 等一元运算符之前,所以

    *a[]      -- is an array of pointer
    (*a)[]    -- is a pointer to an array
    *f()      -- is a function returning a pointer
    (*f)()    -- is a pointer to a function
    

    找到最左边的标识符并解决问题,递归地将这些规则应用于任何函数参数。

    编辑

    在对另一个答案的评论中,KerrekSB 建议使用 typedefs,这肯定会使代码扫描更容易:

    typedef char CharFunc();
    typedef CharFunc *CharFuncPtr;
    typedef CharFuncPtr CharFuncPtrArr[N];
    typedef CharFuncPtrArr *CharFuncPtrArrPtr;
    typedef CharFuncPtrArrPtr CharFuncPtrArrPtrFunc();
    
    CharFuncPtrArrPtrFunc *f;
    

    您可能会想出一个更好的命名约定。但即便如此,

    CharFuncPtrArrPtrFunc *f;
    

    肯定看起来

    char (*(*f())[])();
    

    但它更好吗?

    根据我的经验,答案通常是“否”,尤其是在涉及指针类型时。 f 指向的函数应该是什么样的?我怎么称呼它?我应该传递什么参数给它?我如何处理函数f 指向的返回值?如何在表达式中使用它?我要查CharFuncPtrArrPtrFunc的定义,也就是说我还要查CharFuncPtrArrPtr的定义,还有CharFuncPtrArr等等等等等等,然后我就得脑补一下结果调用的语法。

    char (*(*f())[])(); 几乎完全不可读,但它一目了然地告诉我如何我应该调用函数f 指向以及如何使用返回值。

    【讨论】:

    • 如果投反对票的人能指出他们认为我做错了什么,那就太好了。
    【解决方案2】:

    【讨论】:

    • 这种复杂的声明有什么地方可以学的吗?
    • @Tahil:看这个:C Right-Left Rule
    • @Robert Allan Hennigan Leahy 非常感谢!!
    • @Tahlil:问题是:除了赢得酒吧测验和给女孩留下好印象之外,你为什么要学习这个?对于任何体面的现实世界编程来说,这并不是真正必要的。
    • @Tahlil 因为它是三星级编程(c2.com/cgi/wiki?ThreeStarProgrammer),所以你不应该在实践中使用这样的东西。但是,学习构成这种复杂类型的部分非常有用。就像能够区分char *foo[3];char (*foo)[3] 一样。而且,我相信 SO 是了解这些细节的最佳场所之一。在这方面它教会了我很多...
    猜你喜欢
    • 1970-01-01
    • 2014-09-20
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多