所以我想举一个例子:
int *pi; // pi is a pointer that points to an integer
const int *cpi; // cpi is a pointer that points to a constant integer
char *pc; // pc is a pointer to a char
我如何阅读这些:
char **x; //x is a pointer to a char pointer?
char *y[];
char **z[];
谢谢。
cdecl.org 通常与此类问题有关。毫无疑问,它更容易破译任何复杂的声明,但同时它只是提供了一个抽象的信息。作为 C 或 C++ 程序员,应该知道如何手动破译复杂的声明。螺旋规则在一定程度上有所帮助,但在某些情况下会失败。这个答案将帮助程序员手动破译任何复杂的声明。
记住这两个简单的规则:
- 始终从内到外阅读声明。
- 当有选择时,总是偏爱
[]
,()
胜过*
。
第一条规则只是简单地指出,找到正在声明的变量并开始从中破译声明。
对于第二条规则,如果*
在标识符之前,[]
或()
在标识符后面,则标识符分别表示数组或函数,而不是指针。
示例 1:
char *y[5];
- 变量/标识符
y
。 *
先于y
,在[]
之后。y
必须是数组。
结合上述破译将得到:y
是指向char
的5
指针数组。
另请注意,您始终可以使用括号来覆盖[]
或()
的正常优先级。
示例 2:
void (*pf) (int);
- 变量/标识符
pf
。 *pf
括在括号中,它必须是指针。()
跟随*pf
,表示pf
必须指向一个函数。- 由于
()
包含int
,函数必须期望一个类型为int
的参数。
因此,pf
是一个指向函数的指针,该函数需要int
参数并且不返回任何内容。
现在,在破译以下声明后你会得到什么
int *(*a[5])(void);
?
答:
a
是一个指向函数的指针数组,该函数不需要参数并返回指向int
的指针。
注:注意
char *y[];
char **z[];
如果它们未声明为函数的参数,则会导致编译错误。如果它们是函数的参数,则char *y[]
等价于char **y
,char **z[]
等价于char ***z
。
如果不是这种情况,则需要像我在第一个示例中所做的那样指定维度。
一些示例 C 声明取自HELPPC 实用程序(由 David Jurgens),这些声明在九十年代挽救了我的(编程)生活(该实用程序的在线版本在这里:http://stanislavs.org/helppc
)int i; i as an int
int *i; i as a pointer to an int
int **i; i is a pointer to a pointer to an int
int *(*i)(); i is a pointer to a function returning a
pointer to int
int *(*i[])(); i is an array of pointers to functions
returning pointers to an int
int *i[5]; i is an array of 5 pointers to int
int (*i)[5]; i is a pointer to an array of 5 ints
int *i(); i is a function returning a pointer to an int
int (*i)(); i is a pointer to a function returning int
int *(*(*i)())[5] i is a pointer to a function returning a
pointer to an array of 5 pointers to an int
y
是指向 char 的指针数组,z
是指向 char 的指针数组。x
是指向字符的指针
char **x; //x is a pointer to a pointer to char
char *y[]; // y is an array of pointers to char
char **z[]; // z is an array of pointers to pointers to char