繁体   English   中英

C中这两个令人困惑的函数指针表示法之间的区别?

[英]Difference between these two confusing function pointer notations in C?

C中这两个函数指针符号有什么区别?

void (*a[]())void (*a)()[]

它们是否都表示相同 - 一个指向函数的指针数组 - 或者第二个表示指向函数数组的指针?

我该如何调用这些函数 - 比如void (*a[]()) = {swap, add, sub, prod};

这是否意味着a是4个元素的函数指针数组,而a[0] ... a[3]中有swapaddsubprod的地址。 我该怎么调用这些函数呢?

*a[i]()

或者像这样?

a[i]()

使用cdecl.org来解决这个问题,直到你可以不考虑它为止。

void (*a[]()) :声明一个函数数组,返回指向void的指针

void (*a)()[] :声明一个指向函数返回void的数组的指针

后者无效C.

他们都无效。

void (*a[]());

被解释为

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

您不能声明函数类型的数组。 同样的,

void (*a)()[]

被解释为

       a       -- a
     (*a)      -- is a pointer
     (*a)()    -- to a function
     (*a)()[]  -- returning an array of unknown size
void (*a)()[]  -- of void.

函数不能返回数组类型,也不能有void数组。

如果你想声明一个指向返回void函数的指针数组,你可以将它构建为:

       a          -- a
       a[N]       -- is an N-element array
      *a[N]       -- of pointers
     (*a[N])()    -- to functions
void (*a[N])();   -- returning void

因此, void (*a[N])(); a声明为返回void函数的指针数组。 您将数组中的每个单独函数调用为

(*a[i])();

要么

a[i]();

虽然我更喜欢第一种形式,即使它更混乱。

因此,给定函数列表swapaddsubprod ,您将构建数组

void swap() {...}
void add() {...}
void sub() {...}
void prod() {...}
...
void (*a[])() = {swap, add, sub, prod};
...
(*a[0])(); // calls swap
(*a[1])(); // calls add

给定函数名称,我假设它们采用某种形式的参数。 请注意,数组中的所有函数指针都应具有相同的签名 ; 也就是说,它们都应该具有相同的返回类型,以及相同数量和类型的参数。

当您通过指针调用函数时,C允许您删除显式取消引用,因此您可以将这些函数称为

 a[0]();
 a[1]();

但我更喜欢第一种形式,即使它在视觉上更混乱。

请记住, []和函数调用()优先级高于一元* ,因此T *a[N]声明指向T的指针的N元素数组, T (*a)[N]声明指向T (*a)[N]的指针元素数组TT *f()声明一个函数返回一个指向T的指针, T (*f)()声明一个指向返回T的函数的指针。

根据C中的Right-Left-Rule这里的其他参考),编译器认为这两个表达式都是无效的(也可能是标准的)。

第一个是函数数组,后者是一个空洞数组。

函数返回void的指针数组将是

void (*a[])()

第二个表达式在C中无效,因为它首先不允许void数组,第二个表达式不允许函数返回数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM