右左法則解決複雜宣告

2022-08-25 22:21:19 字數 3522 閱讀 6069

現在很多it公司的面試題都或多或少會有複雜宣告的題,有一點c基礎的人或許能夠瞎搬亂套做對,但這樣你肯定不爽,一方面顯得不專業,有點自欺欺人的感覺,另一方面如果遇到更加複雜的宣告就徹底傻了,本篇主要就一些複雜的宣告介紹一種方法,這個有些書上也有介紹,比如《c專家程式設計》。個人覺得這個沒有必要深究,只做了解即可,很多時候程式設計都很難用到,不過這也是大神和一般程式設計師的區別。

右左法則不是c標準裡面的內容,它是從c標準的宣告規定中歸納出來的方法。c標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如何辯識乙個宣告的。

究竟右左法則的規律是什麼呢?顧名思義,從宣告的右邊看到左邊,下面是左右法則的專業解釋:

右左法則:首先從最裡面的圓括號(應該是未定義的識別符號)看起,然後往右看,再往左看。每當遇到圓括號時,就應該掉轉閱讀方向。一旦解析完圓括號裡面所有的東西,就跳出圓括號。重複這個過程直到整個宣告解析完畢。

下面通過10個例子來說明,由易到難,慢慢加深。

一、例子

(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、 d1ouble (*(*(*fp3)())[10])(), 採用右左法則對此表示式進行分析說明。

2、 int func(void) [5],採用右左法則對此表示式進行分析說明。

3、 int * (* (*fp1) (int) ) [10],採用右左法則對此表示式進行分析說明。

例子答案

(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分解。另外,函式不能宣告返回乙個函式型別。

練習答案:

1、 定義乙個指標指向乙個函式,函式返回值 為乙個指標,指向有10個元素組成的陣列,陣列裡存的是乙個指標,指向乙個函式,函式返回值為double型。

2、 func是乙個引數型別為空,返回值為具有5個int型的陣列的函式。函式的返回值不能為陣列,陣列只能作為右值,所以此函式非法。

3、 定義乙個指標,指向乙個函式,函式引數型別為int型,返回值為乙個指標,指向10個元素組成的int型的指標陣列。

201120 c 右左法則(閱讀複雜宣告必備)

here 理解複雜宣告可用的 右左法則 從變數名看起,先往右,再往左,碰到乙個圓括號就調轉閱讀的方向 括號內分析完就跳出括號,還是按先右後左 的順序,如此迴圈,直到整個宣告分析完。舉例 int func int p 首 先找到變數名func,外面有一對圓括號,而且左邊是乙個 號,這說明func是乙個...

右左法則 複雜指標解析

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

右左法則 複雜指標解析

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