使用左右或螺旋規則來破譯 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