void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
返回类型是 void* 并且 proto_type 是函数的名称?或者这是一个指向函数的指针?有哪些参数:
(long int, char *b)
或这个(const char *b, unsigned short int d)
请解释一下这个功能是如何工作的。
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
返回类型是 void* 并且 proto_type 是函数的名称?或者这是一个指向函数的指针?有哪些参数:
(long int, char *b)
或这个(const char *b, unsigned short int d)
请解释一下这个功能是如何工作的。
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
这是一个函数声明。函数名是proto_type
,它接受两个类型的参数:
long int
char *
并返回一个指向函数的指针
const char*
unsigned short int
并返回void*
。
现在,如果您使用 typedef,以上所有内容都将变得显而易见:
typedef void* function_type(const char *b, unsigned short int d);
function_type* proto_type(long int, char *b);
希望有帮助。
这声明proto_type
为函数获取(long int, char *)
并返回指针,该函数获取 a(const char *, unsigned short int)
并返回 void 指针。
换句话说:
typedef void * (*R)(const char *, unsigned short int); // return type
R proto_type(long int, char *);
我建议为此类问题添加书签www.cdecl.org 。请注意,该页面对您输入的内容有点挑剔(它至少不接受参数名称)。
从函数的名称开始,然后使用通常的表达式语法对其进行评估。因此:
proto_type // proto_type
proto_type( long, char* ) // is a function taking long, char*
// (since function call has precedence over *
*proto_type( long, char* ) // returning a pointer
(*proto_type(...)) // (no change, but necessary for precedence reasons)
(...)( char const*, unsigned short )
// to a function taking char const*, unsigned short
*(...)(...) // returning pointer
void *(...)(...) // to void
(在没有名称的情况下会有点困难,比如 a 中的类型static_cast
。)
我将解释我解析复杂 c 风格声明的过程。我希望你会发现它很有用。
C 风格的解析可以被认为是从标识符开始并以括号为界的从右到左的解析。所以我们从标识符开始proto_type
// vvvvvvvvvv-------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
正如我们所见,从 proto_type 向右移动,我们会立即看到一个函数调用和一些参数,所以这很容易。 proto_type
是一个以long int
和char*
作为参数的函数。
// v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
在这里,我们点击了第一个边界括号,所以我们必须向后查找下一个标记:
// v----------------------------
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
所以现在我们知道它返回一个指向某个东西的指针。现在我们必须再次向右看,以再次找出括号的原因
// v--------------------------------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
const char*
由于我们找到了另一个函数调用运算符,它返回的指针必须是一个指向带有 a和 an的函数的指针unsigned short int
。
最后,我们到达了另一个边界括号,所以向左移动以找到该函数指针的返回值。
//vvvv----------------------------------------------------------------------v
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
函数指针返回一个 void* 作为返回值。
所以用英语概括一下: proto_type
将 along int
和 achar*
作为参数并返回一个指向函数的指针,该函数将 aconst char*
和unsigned short int
作为参数并返回 a void*
。
在 Windows 8 x64 上使用 VS2012。
proto_type
是一个接受 a long int
(未命名)和unsigned short int d
a 的函数,并返回一个形式为void * proto2(const char *b, unsigned short int d);
这是一些工作代码:
#include <stddef.h>
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d);
void * proto2(const char *b, unsigned short int d);
int main(int argc, char** argv){
if(proto_type(0, NULL)(NULL, 0) != (void*)8675309)
return 0;
else
return 1;
}
void * (*proto_type(long int, char *b)) (const char *b, unsigned short int d){
return &proto2;
}
void* proto2(const char *b, unsigned short int d){
return (void*)8675309;
}
发生的事情是main
调用proto_type
返回一个指向的指针proto2
,它main
立即调用。proto2
返回一个我们在 中检查的魔术指针值main
。
这是 VS2012 的调试输出:
The program '[3188] test.exe' has exited with code 1 (0x1).
至于“这个功能是如何工作的”,答案是你想要的(假设你是实现它的人)。
如果您想以另一种方式查看它,则需要从里到外阅读它以了解调用函数的顺序。
这里的教训是 C(++) 函数指针非常不透明。
我已经完成了@Tomek 所说的操作,并将您的原型复制到 http:www.cdel.org,然后从原型中删除了参数名称:
void * (*proto_type(long int, char *)) (const char *, unsigned short int );
按回车,网站返回:
declare proto_type as function (long int, pointer to char) returning pointer
to function (pointer to const char, unsigned short int) returning pointer
to void
现在,把它翻译成碳单元说话:proto_type 被声明为一个函数,它接受 along int
和一个指向 achar
作为参数的指针,它返回一个指向一个函数的指针,该函数接受一个指向 aconst char
和 an的指针,unsigned short integer
并且该函数返回 a void pointer
。
最后,void pointer
可以将 a 转换为指向任何其他数据类型的指针。
proto_type
是一个函数,它有两个参数,long int
并且char *
. 它返回一个函数指针,它接受两个类型为 const char *
和的参数unsigned short int
。
并且不使用 typedef 来写这个对读者来说不是很友好。