使用左右或螺旋规则来破译 C 声明
“右 - 左”规则是解密 C 声明的完全规则规则。它在创建它们时也很有用。
在声明中遇到符号时读取符号…
* as "pointer to" - always on the left side
[] as "array of" - always on the right side
() as "function returning" - always on the right side
如何应用规则
步骤 1
找到标识符。这是你的出发点。然后对自己说,“标识符是。” 你已经开始声明了。
第 2 步
查看标识符右侧的符号。如果你在那里找到 ()
,那么你知道这是函数的声明。所以你会有 标识符是函数返回 。或者如果你在那里发现了一个 []
,你会说 标识符就是数组 。继续向右,直到你的符号用完或点击右括号 )
。 (如果你点左括号 (
,那就是 ()
符号的开头,即使括号之间有东西。更多信息如下。)
第 3 步
查看标识符左侧的符号。如果它不是我们上面的符号之一(比如 int
之类的东西),那就说吧。否则,使用上表将其翻译成英文。继续向左走,直到你的符号用尽或点击左括号 (
。
现在重复步骤 2 和 3,直到你形成声明。
这里有些例子:
int *p[];
首先,找到标识符:
int *p[];
^
是的
现在,向右移动直到符号或右括号命中。
int *p[];
^^
“p 是数组”
不能再向右移动(符号外),所以向左移动并找到:
int *p[];
^
“p 是指针的数组”
继续往前走,找到:
int *p[];
^^^
“p 是指向 int 的指针数组”。
(或 “p 是一个数组,其中每个元素都是指向 int 的类型指针” )
另一个例子:
int *(*func())();
找到标识符。
int *(*func())();
^^^^
func is
向右移。
int *(*func())();
^^
“func 是函数返回”
由于右括号,不能再向右移动,所以向左移动。
int *(*func())();
^
“func 是函数返回指针”
由于左括号,不能再向左移动,所以继续向右走。
int *(*func())();
^^
“func 是函数返回指向函数返回的指针”
由于我们没有符号,所以不能再向右移动了,所以请左移。
int *(*func())();
^
“func 是函数返回指向函数返回指针的指针”
最后,继续向左走,因为右边没有任何东西。
int *(*func())();
^^^
“func 是函数返回指向函数的指针,返回指向 int 的指针”。
如你所见,此规则非常有用。你还可以在创建声明时使用它来检查自己,并提供有关放置下一个符号的位置以及是否需要括号的提示。
由于原型形式的数组大小和参数列表,一些声明看起来比它们复杂得多。如果你看到 [3]
,那就读作 “……的数组(大小 3)” 。如果你看到 (char *,int)
被读作*“函数期待(char ,int)并返回……” 。
这是一个有趣的:
int (*(*fun_one)(char *,double))[9][20];
我不会通过每个步骤来破译这个。
*“fun_one 是指向函数期望(char ,double)的指针,并返回指向 int 的数组(大小为 20)的数组(大小为 9)的指针。”
如你所见,如果你摆脱数组大小和参数列表,它就不那么复杂了:
int (*(*fun_one)())[][];
你可以用这种方式解密它,然后再输入数组大小和参数列表。
最后一句话:
很有可能使用此规则进行非法声明,因此必须了解 C 语言中的合法性。例如,如果以上是:
int *((*fun_one)())[][];
它会读取 “fun_one 是指向函数的指针返回指向 int 的数组的数组” 。由于函数不能返回数组,而只返回指向数组的指针,因此该声明是非法的。
非法组合包括:
[]() - cannot have an array of functions
()() - cannot have a function that returns a function
()[] - cannot have a function that returns an array
在上述所有情况下,你需要一组括号来绑定这些 ()
和 []
右侧符号之间左侧的*
符号,以使声明合法。
以下是一些例子:
int i; an int
int *p; an int pointer (ptr to an int)
int a[]; an array of ints
int f(); a function returning an int
int **pp; a pointer to an int pointer (ptr to a ptr to an int)
int (*pa)[]; a pointer to an array of ints
int (*pf)(); a pointer to a function returning an int
int *ap[]; an array of int pointers (array of ptrs to ints)
int aa[][]; an array of arrays of ints
int *fp(); a function returning an int pointer
int ***ppp; a pointer to a pointer to an int pointer
int (**ppa)[]; a pointer to a pointer to an array of ints
int (**ppf)(); a pointer to a pointer to a function returning an int
int *(*pap)[]; a pointer to an array of int pointers
int (*paa)[][]; a pointer to an array of arrays of ints
int *(*pfp)(); a pointer to a function returning an int pointer
int **app[]; an array of pointers to int pointers
int (*apa[])[]; an array of pointers to arrays of ints
int (*apf[])(); an array of pointers to functions returning an int
int *aap[][]; an array of arrays of int pointers
int aaa[][][]; an array of arrays of arrays of int
int **fpp(); a function returning a pointer to an int pointer
int (*fpa())[]; a function returning a pointer to an array of ints
int (*fpf())(); a function returning a pointer to a function returning an int
非法
int af[](); an array of functions returning an int
int fa()[]; a function returning an array of ints
int ff()(); a function returning a function returning an int
int (*pfa)()[]; a pointer to a function returning an array of ints
int aaf[][](); an array of arrays of functions returning an int
int (*paf)[](); a pointer to a an array of functions returning an int
int (*pff)()(); a pointer to a function returning a function returning an int
int *afp[](); an array of functions returning int pointers
int afa[]()[]; an array of functions returning an array of ints
int aff[]()(); an array of functions returning functions returning an int
int *fap()[]; a function returning an array of int pointers
int faa()[][]; a function returning an array of arrays of ints
int faf()[](); a function returning an array of functions returning an int
int *ffp()(); a function returning a function returning an int pointer