【问题标题】:What does double* (*p[3]) (void* (*)()); mean?double* (*p[3]) (void* (*)()); 是什么意思?意思是?
【发布时间】:2012-06-09 21:58:49
【问题描述】:

我很难理解以下声明的含义。这是申报标准吗?

double* (*p[3]) (void* (*)());

谁能帮我理解这个声明的含义?

【问题讨论】:

  • 我很高兴走进 Java 世界...
  • ...而不是在 C 世界中运行? ;-)
  • Oli Charlesworth 提供了一个普遍有用的答案。不要关闭。
  • 应该作为副本关闭,例如stackoverflow.com/questions/6437333/…

标签: c pointers


【解决方案1】:

读取多毛声明的规则:找到最左边的标识符并向外工作,记住()[]*之前绑定,所以T *a[N]是一个指向T的指针数组,T (*a)[N]是指向 T 数组的指针,T *f() 是返回指向 T 的指针的函数,T (*f)() 是指向返回 T 的函数的指针。由于函数原型可能会省略参数名称,因此您可能会看到一些东西比如T *[N]T (*)()。意思大致相同1,只是假装有一个长度为0的标识符。

因此,

          p                      -- p
          p[3]                   -- is a 3-element array
         *p[3]                   -- of pointers
        (*p[3]) (           )    -- to functions
        (*p[3]) (      (*)())    --   taking a pointer to a function
        (*p[3]) (    * (*)())    --   returning a pointer
        (*p[3]) (void* (*)())    --   to void
      * (*p[3]) (void* (*)())    -- returning a pointer
double* (*p[3]) (void* (*)());   -- to double

这里要指出的重要一点是,您将p 声明为...数组,而不是返回... 的函数。

这样的野兽在实践中会是什么样子?好吧,首先,您需要指向三个函数。这些函数中的每一个都有一个参数,它是一个指向函数的指针,该函数返回一个指向 void 的指针:

double *foo(void *(*)());
double *bar(void *(*)());
double *bletch(void *(*)());

double *(*p[3]) (void *(*)()) = {foo, bar, bletch};

foobarbletch 中的每一个都会调用传递给它的函数并以某种方式返回指向 double 的指针。

您还想为foobarbletch 中的每一个定义一个或多个满足参数类型的函数:

void *blurga() {...}

所以如果你直接打电话给foo,你会这样称呼它

double *pv;
...
pv = foo(blurga);

所以我们可以想象这样的电话

double *pv = (*p[0])(blurga);


1 - 区别在于在函数参数声明的上下文中,T a[]T a[N]T *a 相同;在这三种情况下,a 是一个指针 T,而不是T 的数组。请注意,这在函数参数声明中为真。因此,T *[] 将等同于 T **

【讨论】:

    【解决方案2】:

    只需使用http://cdecl.org:

    将 p 声明为指向函数的指针数组 3(指向函数的指针返回指向 void 的指针)返回指向双精度的指针

    有关详细信息,请参阅此 MSDN 文章:Interpreting more complex declarators

    但 typedef 会有所帮助:

    typedef void *(*foo)();         // foo is a function-pointer type
    typedef double *(*bar)(foo);    // bar is also a function-pointer type
    bar p[3];
    

    (显然,使用适当的名称代替foobar!)

    【讨论】:

    • 我在 +1 之前从未见过那个网站
    • +1 用于链接你的智慧之源,而不是让它看起来像是你自己变出来的。 ;-)
    • @DevSolar - 认为 cdecl 是每个人理解难看的 C 声明的唯一方法是不公平的。
    • ...在提出问题的一分钟内?这也不可惜,我想我从来没有解读过函数指针声明没有 cdecl。
    • @DevSolar:公平地说,一旦记住了“算法”(如我链接到的文章中所述),手动执行此操作不是问题。
    【解决方案3】:

    您的 p 是一个 3 个指针的数组,指向一个返回 double 指针的函数,并将一个指向另一个函数的指针作为参数,该函数返回一个 void 指针,并且不需要论据。

    但是,不要使用这种语法,请尝试使用 typedef。

    【讨论】:

    • 我也是,但我喜欢 Oli 的链接,“众所周知,我教我钓鱼”:)
    【解决方案4】:

    它是一个函数指针数组(大小为 3),它返回指向 double 的指针并将另一个函数指针作为参数。

    指针可以存储在数组中的函数类型:double *(func)(void* (*)())
    指针可作为参数传递给 func 的函数类型:void *(func1)(void)

    【讨论】:

    • +1 因为这是最容易理解的描述(对我来说)。
    【解决方案5】:

    “有一种称为“顺时针/螺旋规则”的技术,可以让任何 C 程序员在头脑中解析任何 C 声明!”

    顺时针螺旋规则 - http://c-faq.com/decl/spiral.anderson.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-01
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 2014-09-21
      • 2019-11-19
      相关资源
      最近更新 更多