我的位置: 首頁 > 學(xué)習(xí)專區(qū) > .NET技術(shù) > C語言右左法則----復(fù)雜指針解析

C語言右左法則----復(fù)雜指針解析

2013-06-04 09:17:23
來源:
[導(dǎo)讀] 因?yàn)镃語言所有復(fù)雜的指針聲明,都是由各種聲明嵌套構(gòu)成的。如何解讀復(fù)雜指針聲明呢?右左法則是一個(gè)既著名又常用的方法。不過,右左法則其實(shí)...

因?yàn)镃語言所有復(fù)雜的指針聲明,都是由各種聲明嵌套構(gòu)成的。如何解讀復(fù)雜指針聲明呢?右左法則是一個(gè)既著名又常用的方法。不過,右左法

則其實(shí)并不是C標(biāo)準(zhǔn)里面的內(nèi)容,它是從C標(biāo)準(zhǔn)的聲明規(guī)定中歸納出來的方法。C標(biāo)準(zhǔn)的聲明規(guī)則,是用來解決如何創(chuàng)建聲明的,而右左法則是用

來解決如何辯識一個(gè)聲明的,兩者可以說是相反的。右左法則的英文原文是這樣說的:

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.

這段英文的翻譯如下:

右左法則:首先從最里面的圓括號看起,然后往右看,再往左看。每當(dāng)遇到圓括號時(shí),就應(yīng)該掉轉(zhuǎn)閱讀方向。一旦解析完圓括號里面所有的東西,就跳出圓括號。重復(fù)這個(gè)過程直到整個(gè)聲明解析完畢。

筆者要對這個(gè)法則進(jìn)行一個(gè)小小的修正,應(yīng)該是從未定義的標(biāo)識符開始閱讀,而不是從括號讀起,之所以是未定義的標(biāo)識符,是因?yàn)橐粋€(gè)聲明里面可能有多個(gè)標(biāo)識符,但未定義的標(biāo)識符只會有一個(gè)。

現(xiàn)在通過一些例子來討論右左法則的應(yīng)用,先從最簡單的開始,逐步加深:

int (*func)(int *p);

首先找到那個(gè)未定義的標(biāo)識符,就是func,它的外面有一對圓括號,而且左邊是一個(gè)*號,這說明func是一個(gè)指針,然后跳出這個(gè)圓括號,先看

右邊,也是一個(gè)圓括號,這說明(*func)是一個(gè)函數(shù),而func是一個(gè)指向這類函數(shù)的指針,就是一個(gè)函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值類型是 int。

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

func被一對括號包含,且左邊有一個(gè)*號,說明func是一個(gè)指針,跳出括號,右邊也有個(gè)括號,那么func是一個(gè)指向函數(shù)的指針,這類函數(shù)具有int *和int (*)(int*)這樣的形參,返回值為int類型。再來看一看func的形參int (*f)(int*),類似前面的解釋,f也是一個(gè)函數(shù)指針,指向的函數(shù)具有int*類型的形參,返回值為int。

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

func右邊是一個(gè)[]運(yùn)算符,說明func是一個(gè)具有5個(gè)元素的數(shù)組,func的左邊有一個(gè)*,說明func的元素是指針,要注意這里的*不是修飾 func的,而是修飾func[5]的,原因是[]運(yùn)算符優(yōu)先級比*高,func先跟[]結(jié)合,因此*修飾的是func[5]。跳出這個(gè)括號,看右邊,也是一對圓括號,說明func數(shù)組的元素是函數(shù)類型的指針,它所指向的函數(shù)具有int*類型的形參,返回值類型為int。

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

func被一個(gè)圓括號包含,左邊又有一個(gè)*,那么func是一個(gè)指針,跳出括號,右邊是一個(gè)[]運(yùn)算符號,說明func是一個(gè)指向數(shù)組的指針,現(xiàn)在往左看,左邊有一個(gè)*號,說明這個(gè)數(shù)組的元素是指針,再跳出括號,右邊又有一個(gè)括號,說明這個(gè)數(shù)組的元素是指向函數(shù)的指針。總結(jié)一下,就是:func是一個(gè)指向數(shù)組的指針,這個(gè)數(shù)組的元素是函數(shù)指針,這些指針指向具有int*形參,返回值為int類型的函數(shù)。

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

func是一個(gè)函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值是指向數(shù)組的指針,所指向的數(shù)組的元素是具有5個(gè)int元素的數(shù)組。

要注意有些復(fù)雜指針聲明是非法的,例如:

int func(void) [5];

func是一個(gè)返回值為具有5個(gè)int元素的數(shù)組的函數(shù)。但C語言的函數(shù)返回值不能為數(shù)組,這是因?yàn)槿绻试S函數(shù)返回值為數(shù)組,那么接收這個(gè)數(shù)組的內(nèi)容的東西,也必須是一個(gè)數(shù)組,但C語言的數(shù)組名是一個(gè)右值,它不能作為左值來接收另一個(gè)數(shù)組,因此函數(shù)返回值不能為數(shù)組。

int func[5](void);

func是一個(gè)具有5個(gè)元素的數(shù)組,這個(gè)數(shù)組的元素都是函數(shù)。這也是非法的,因?yàn)閿?shù)組的元素除了類型必須一樣外,每個(gè)元素所占用的內(nèi)存空間也必須相同,顯然函數(shù)是無法達(dá)到這個(gè)要求的,即使函數(shù)的類型一樣,但函數(shù)所占用的空間通常是不相同的。

作為練習(xí),下面列幾個(gè)復(fù)雜指針聲明給讀者自己來解析。

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

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

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

實(shí)際當(dāng)中,需要聲明一個(gè)復(fù)雜指針時(shí),如果把整個(gè)聲明寫成上面所示的形式,對程序可讀性是一大損害。應(yīng)該用typedef來對聲明逐層

分解,增強(qiáng)可讀性,例如對于聲明:

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

可以這樣分解:

typedef int (*PARA)[5];

typedef PARA (*func)(int *);

這樣就容易看得多了。

答案,同時(shí)給出用typedef的分解方法:

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

func是一個(gè)指向數(shù)組的指針,這類數(shù)組的元素是一個(gè)具有5X6個(gè)int元素的二維數(shù)組,而這個(gè)二維數(shù)組的元素又是一個(gè)二維數(shù)組。

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

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

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

func是一個(gè)函數(shù)指針,這類函數(shù)的返回值是一個(gè)指向數(shù)組的指針,所指向數(shù)組的元素也是函數(shù)指針,指向的函數(shù)具有int*形參,返回值為int。

typedef int (*PARA1)(int*);

typedef PARA1 (*PARA2)[5];

typedef PARA2 (*func)(int*);

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

func是一個(gè)數(shù)組,這個(gè)數(shù)組的元素是函數(shù)指針,這類函數(shù)具有int*的形參,返回值是指向數(shù)組的指針,所指向的數(shù)組的元素是具有5個(gè)int元素

的數(shù)組。

typedef int (*PARA1)[5];

typedef PARA1 (*PARA2)(int*);

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

深圳北大青鳥嘉華校區(qū)

評論
熱點(diǎn)專題
>>
相關(guān)文章推薦
>>
好吊妞免费视频在线观看,久久亚洲国产人成综合网,久久精品国产2020,欧美精品综合在线
尹人香蕉久久99天天拍国产 | 又紧又爽又深精品视频一区二区 | 在线不卡日本v一区ⅴ二区 一区二区三区在线|欧黑人 | 伊久线香蕉观新综合在线动漫 | 综合卡通欧美日韩亚洲 | 久久精品国产高清 |