2

C中这两种函数指针表示法有什么区别?

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

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

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

这是否意味着这a是一个由 4 个元素组成的函数指针数组,并且swap, add, sub,prod的地址在a[0]...a[3]中。我应该如何调用这些函数,像这样?

*a[i]()

还是这样?

a[i]()
4

4 回答 4

6

使用cdecl.org来解决这些问题,直到您可以不假思索地做到这一点。

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

然而

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

后者无效 C.

于 2012-05-20T06:39:30.873 回答
5

他们都是无效的。

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]();

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

因此,给定函数swapaddsub和的列表prod,您可以将数组构建为

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]声明指向 的 N 元素数组,声明指向 的 N 元素数组的指针,声明T返回指向的指针的函数,并声明指向返回的函数的指针.T (*a)[N]TT *f()TT (*f)()T

于 2012-05-20T13:31:47.067 回答
4

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

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

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

void (*a[])()

.

于 2012-05-20T06:39:16.947 回答
0

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

于 2012-05-20T06:39:47.710 回答