右左法則 複雜指標解析

2021-06-18 03:50:25 字數 3653 閱讀 2234

右左法則不是c標準裡面的內容,它是從c

標準的宣告規定中歸納出來的方法。c

標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如何辯識乙個宣告的,兩者可以說是相反的。

右左法則原文:

the right-left rule:start reading the declaration from the innermost parentheses,go right,and then go left.when you encounter parentheses, the direction should be reversed.once everything in the parentheses has been parsed, jump out of it.continue till the whole declaration has been parsed.

右左法則譯文:

右左法則:首先從最裡面的

圓括號(

應該是未定義的識別符號

)看起,然後往右看,再往左看。每當遇到圓括號時,就應該掉轉閱讀方向。一旦解析完圓括號裡面所有的東西,就跳出圓括號。重複這個過程直到整個宣告解析完畢。

現在通過一些例子來討論右左法則的應用,先從最簡單的開始,逐步加深。

(1)int (*func)(int *p);

(2)int (*func)(int *p, int (*f)(int*));

(3)int (*func[5])(int *p);

(4)int (*(*func)[5])(int *p);

(5)int (*(*func)(int *p))[5];

(6)int func(void) [5]; //錯誤

(7)int func[5](void); //錯誤

(8)int (*(*func)[5][6])[7][8];

(9)int (*(*(*func)(int *))[5])(int *);

(10)int (*(*func[7][8][9])(int*))[5];

解答:(1

)int (*func)(int *p);

首先找到那個未定義的識別符號,就是func

,它的外面有一對圓括號,而且左邊是乙個*

號,這說明func

是乙個指標,然後跳出這個圓括號,先看右邊,也是乙個圓括號,這說明(*func)

是乙個函式,而func

是乙個指向這類函式的指標,就是乙個函式指標,這類函式具有int*

型別的形參,返回值型別是 int。

(2)int (*func)(int *p, int (*f)(int*));

func被一對括號包含,且左邊有乙個*

號,說明func

是乙個指標,跳出括號,右邊也有個括號,那麼func

是乙個指向函式的指標,這類函式具有int *

和int (*)(int*)

這樣的形參,返回值為int

型別。再來看一看func

的形參int (*f)(int*)

,類似前面的解釋,f

也是乙個函式指標,指向的函式具有int*

型別的形參,返回值為int。

(3)int (*func[5])(int *p);

func右邊是乙個

運算子,說明func

是乙個具有5

個元素的陣列,func

的左邊有乙個*

,說明func

的元素是指標,要注意這裡的*

不是修飾 func

的,而是修飾func[5]

的,原因是

運算子優先順序比*

高,func

先跟結合,因此*

修飾的是func[5]

。跳出這個括號,看右邊,也是一對圓括號,說明func

陣列的元素是函式型別的指標,它所指向的函式具有int*

型別的形參,返回值型別為int。(4

)int (*(*func)[5])(int *p);

func被乙個圓括號包含,左邊又有乙個*

,那麼func

是乙個指標,跳出括號,右邊是乙個

運算符號,說明func

是乙個指向陣列的指標,現在往左看,左邊有乙個*

號,說明這個陣列的元素是指標,再跳出括號,右邊又有乙個括號,說明這個陣列的元素是指向函式的指標。總結一下,就是:func

是乙個指向陣列的指標,這個陣列的元素是函式指標,這些指標指向具有int*

形參,返回值為int

型別的函式。

(5)int (*(*func)(int *p))[5];

func是乙個函式指標,這類函式具有int*

型別的形參,返回值是指向陣列的指標,所指向的陣列的元素是具有5

個int

元素的陣列。

要注意有些複雜指標宣告是非法的,例如:

(6)int func(void) [5];

func是乙個返回值為具有5

個int

元素的陣列的函式。但c

語言的函式返回值不能為陣列,這是因為如果允許函式返回值為陣列,那麼接收這個陣列的內容的東西,也必須是乙個陣列,但c

語言的陣列名是乙個右值,它不能作為左值來接收另乙個陣列,因此函式返回值不能為陣列。

(7)int func[5](void);

func是乙個具有5

個元素的陣列,這個陣列的元素都是函式。這也是非法的,因為陣列的元素除了型別必須一樣外,每個元素所占用的記憶體空間也必須相同,顯然函式是無法達到這個要求的,即使函式的型別一樣,但函式所占用的空間通常是不相同的。

(8)int (*(*func)[5][6])[7][8];

func是乙個指向陣列的指標,這類陣列的元素是乙個具有5x6

個int

元素的二維陣列,而這個二維陣列的元素又是乙個二維陣列。typedef

分解:

typedef int (*para)[7][8];

typedef para (*func)[5][6];

(9)int (*(*(*func)(int *))[5])(int *);

func是乙個函式指標,這類函式的返回值是乙個指向陣列的指標,所指向陣列的元素也是函式指標,指向的函式具有int*

形參,返回值為int

。typedef

分解:

typedef int (*para1)(int*);

typedef para1 (*para2)[5];

typedef para2 (*func)(int*);

(10)int (*(*func[7][8][9])(int*))[5];

func是乙個陣列,這個陣列的元素是函式指標,這類函式具有int*

的形參,返回值是指向陣列的指標,所指向的陣列的元素是具有5

個int

元素的陣列。typedef

分解:

typedef int (*para1)[5];

typedef para1 (*para2)(int*);

typedef para2 func[7][8][9];

【小結】實際當中,需要宣告乙個複雜指標時,如果把整個宣告寫成上面所示的形式,對程式可讀性是一大損害。應該用

typedef

來對宣告逐層分解,增強可讀性。

例子(8

)(9)(10

)給出了typedef

分解。另外,函式不能宣告返回乙個函式型別。

右左法則 複雜指標解析

第八章 右左法則 複雜指標解析 上一章費那麼多唇舌討論c語言的宣告,其實目的都是為了這一章,期望讀者通過對c語言宣告形式的詳細了解,樹立宣告巢狀的觀念,因為c語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是乙個既著名又常用的方法。不過,右左法則其實並不是c標準裡面...

右左法則 複雜指標解析

因為c語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是乙個既著名又常用的方法。不過,右左法 則其實並不是c標準裡面的內容,它是從c標準的宣告規定中歸納出來的方法。c標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用 來解決如何辯識乙個宣告的,兩者可以說是相反...

右左法則 複雜指標解析

因為c語言所有複雜的指標宣告,都是由各種宣告巢狀構成的。如何解讀複雜指標宣告呢?右左法則是乙個既著名又常用的方法。不過,右左法則其實並不是c標準裡面的內容,它是從c標準的宣告規定中歸納出來的方法。c標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如何辯識乙個宣告的,兩者可以說是相反的。...