我很难理解以下声明的含义。这是申报标准吗?
double* (*p[3]) (void* (*)());
谁能帮我理解这个声明的含义?
阅读毛茸茸的声明的规则:找到最左边的标识符并向外工作,记住它()
并[]
在之前绑定*
,因此T *a[N]
是指针数组,是指向数组的指针,是T
返回指向指针的函数,并且是指向 a 的指针返回 T 的函数。由于函数原型可能会省略参数名称,因此您可能会看到类似or的内容。含义大致相同1,只是假设有一个长度为 0 的标识符。 T (*a)[N]
T
T *f()
T
T (*f)()
T *[N]
T (*)()
因此,
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};
每个foo
,bar
和bletch
都会调用传递给它的函数并以某种方式返回指向double
.
您还需要定义一个或多个满足 、 和 中的每一个的参数类型foo
的bar
函数bletch
:
void *blurga() {...}
所以如果你foo
直接打电话,你会这样称呼它
double *pv;
...
pv = foo(blurga);
所以我们可以想象一个像
double *pv = (*p[0])(blurga);
T a[]
和;T a[N]
相同 T *a
在所有三种情况下,a
是指向 的指针 T
,而不是 的数组T
。请注意,这只适用于函数参数声明。因此,T *[]
将与 相同T **
。
只需使用http://cdecl.org:
将 p 声明为指向函数的指针数组 3(指向函数的指针,返回指向 void 的指针)返回指向 double 的指针
有关详细信息,请参阅此 MSDN 文章:解释更复杂的声明符。
但是 typedefs 会有所帮助:
typedef void *(*foo)(); // foo is a function-pointer type
typedef double *(*bar)(foo); // bar is also a function-pointer type
bar p[3];
(显然,使用适当的名称代替foo
and bar
!)
你p
是一个由 3 个指针组成的数组,指向一个返回指针的double
函数,并将指向另一个返回void
指针且不带参数的函数的指针作为参数。
但是,不要使用这种语法,而是尝试使用 typedef。
它是函数指针数组(大小为 3),它返回指向 double 的指针并将另一个函数指针作为参数。
指针可以存储在数组 double *(func)(void* (*)())
中的函数类型: 指针可以作为参数传递给 func 的函数类型:void *(func1)(void)
“有一种称为‘顺时针/螺旋规则’的技术,它使任何 C 程序员都能在头脑中解析任何 C 声明!”