C中的混合指针,数组和函数类型声明

时间:2009-08-26 01:26:56

标签: c

我的一个朋友试图用C测试我(我最强的语言是C ++),他问我三个我无法回答的问题:

尝试解释以下声明:

1) int (*x)(int, char *, void *);
2) int (*x[10])(int, char *, void *);
3) int (**x[10])(int, char *, void *);

任何人都可以解释这些函数声明并解释正在使用的概念吗?

5 个答案:

答案 0 :(得分:31)

您需要cdecl计划,这将为您提供明确,正确的答案。学习如何手动解释这些语句是可行和有益的,但即便如此,cdecl对于检查你是否有正确的答案非常有用。

prompt>cdecl
Type `help' or `?' for help
cdecl> explain int (*x)(int, char *, void *);
declare x as pointer to function (int, pointer to char, pointer to void) returning int
cdecl> explain int (*x[10])(int, char *, void *);
declare x as array 10 of pointer to function (int, pointer to char, pointer to void) returning int
cdecl> explain int (**x[10])(int, char *, void *);
declare x as array 10 of pointer to pointer to function (int, pointer to char, pointer to void) returning int
cdecl>

答案 1 :(得分:21)

嗯,第一个是指向函数的指针。换句话说,它声明了一个变量“x”,它指向以下类型的函数:

int function(int, char*, void*);

可以使用如下:

int myfunc(int a, char* b, void* c) {
    return a;
}

void acallingfunction() {
    int (*x)(int, char*, void*);
    x = myfunc;
    x(1, "hello", 0);
}

第二个似乎是无效的语法,但我可能是错的。如果它在x之前有一个星号(例如int(* x [10])(int,char *,void *)),它将是一个函数指针数组,并且将像普通数组一样使用:

x[3](1, "Hi there", 0);

第三个是指向函数指针的指针数组,这看似不实用,但完全有效。示例用法可能是:

void anothercaller() {
    int (*x)(int, char*, void*);
    int (**y)(int, char*, void*);
    x = myfunc;
    y = &x;
    (*y)(1, "hello", 0);
}

请注意,其中前两个比较常见。指向函数的指针用于在C中完成回调和各种面向对象的编程概念。函数指针数组可用于事件表,以找到适当的回调。

请注意,所有这些实际上都是有效的C ++。 ;)

编辑:我显然犯了void main()的暴行。

编辑2:正如Chris Lutz在下面指出的那样,他们真的应该用typedef包装。 Typedef使包含函数指针的代码更加清晰。

答案 2 :(得分:7)

  1. 函数指针
  2. 一系列函数指针
  3. 指向函数指针的指针数组

答案 3 :(得分:6)

如上所述,它们是函数指针,但写得相当令人讨厌(在我看来)。我写它们的方式是:

typedef int (*funcptr)(int, char *, void *);

funcptr x;
funcptr x[10];
funcptr *x;

有关函数指针的更多信息,请参阅Walt W's excellent answer

答案 4 :(得分:3)

由于C的语法就像这个问题中的C ++,geordi对你来说很有意思。它是另一个用于教授和学习这些声明的好工具(以及与C ++相关的其他事情,有时也与C相关)。

geordi: << ETYPE_DESC(x); int (*x)(int, char *, void *);
lvalue pointer to a function taking an integer, a pointer to a character, a pointer to anything, and returning an integer

geordi: << ETYPE_DESC(x); int (*x[10])(int, char *, void *);
lvalue array of 10 pointers to functions taking an integer, a pointer to a character, a pointer to anything, and returning integers

geordi: << ETYPE_DESC(x); int (**x[10])(int, char *, void *);
lvalue array of 10 pointers to pointers to functions taking an integer, a pointer to a character, a pointer to anything, and returning integers

正如其页面所解释的,它可以做更多事情,包括为你构建一个类型

geordi: make type array of 10 pointers to functions taking an integer and returning void
void(*[10])(int)

如果你原则上知道如何宣布事情,但不确定一件事,你可以使用括号:

geordi: make type ( void(int, bool) )*
void(*)(int, bool)

如果您想查看其中包含标识符的情况,您也可以更改名称类型

geordi: -c int x;
Success
geordi: make x a ( void(int, bool) )* and show
-c void (* x)(int, bool) ;

如果你建立了一个声明,但是你不确定运算符的优先级,那么geordi的优先级函数可以帮助你

geordi: precedence *x(a, b)
*(x(a, b))
相关问题