青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

右左法則----復雜指針解析

首先看看如下一個聲明:

 

int* ( *( *fun )( int* ) )[10];

 

這是一個會讓初學者感到頭暈目眩、感到恐懼的函數(shù)指針聲明。在熟練掌握C/C++的聲明語法之前,不學習一定的規(guī)則,想理解好這類復雜聲明是比較困難的。

 

C/C++所有復雜的聲明結構,都是由各種聲明嵌套構成的。如何解讀復雜指針聲明?右左法則是一個很著名、很有效的方法。不過,右左法則其實并不是C/C++標準里面的內容,它是從C/C++標準的聲明規(guī)定中歸納出來的方法。C/C++標準的聲明規(guī)則,是用來解決如何創(chuàng)建聲明的,而右左法則是用來解決如何辯識一個聲明的,從嵌套的角度看,兩者可以說是一個相反的過程。右左法則的英文原文是這樣說的:

 

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.

 

 

這段英文的翻譯如下:

 

右左法則:首先從最里面的圓括號看起,然后往右看,再往左看。每當遇到圓括號時,就應該掉轉閱讀方向。一旦解析完圓括號里面所有的東西,就跳出圓括號。重復這個過程直到整個聲明解析完畢。

 

    筆者要對這個法則進行一個小小的修正,應該是從未定義的標識符開始閱讀,而不是從括號讀起,之所以是未定義的標識符,是因為一個聲明里面可能有多個標識符,但未定義的標識符只會有一個。

 

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

 

int (*func)(int *p);

 

首先找到那個未定義的標識符,就是func,它的外面有一對圓括號,而且左邊是一個*號,這說明func是一個指針,然后跳出這個圓括號,先看右邊,也是一個圓括號,這說明(*func)是一個函數(shù),而func是一個指向這類函數(shù)的指針,就是一個函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值類型是int

 

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

 

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

 

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

 

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

 

 

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

 

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

 

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

 

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

 

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

 

int func(void) [5];

 

func是一個返回值為具有5int元素的數(shù)組的函數(shù)。但C語言的函數(shù)返回值不能為數(shù)組,這是因為如果允許函數(shù)返回值為數(shù)組,那么接收這個數(shù)組的內容的東西,也必須是一個數(shù)組,但C/C++語言的數(shù)組名是一個不可修改的左值,它不能直接被另一個數(shù)組的內容修改,因此函數(shù)返回值不能為數(shù)組。

 

int func[5](void);

 

func是一個具有5個元素的數(shù)組,這個數(shù)組的元素都是函數(shù)。這也是非法的,因為數(shù)組的元素必須是對象,但函數(shù)不是對象,不能作為數(shù)組的元素。

 

實際編程當中,需要聲明一個復雜指針時,如果把整個聲明寫成上面所示這些形式,將對可讀性帶來一定的損害,應該用typedef來對聲明逐層分解,增強可讀性。

 

typedef是一種聲明,但它聲明的不是變量,也沒有創(chuàng)建新類型,而是某種類型的別名。typedef有很大的用途,對一個復雜聲明進行分解以增強可讀性是其作用之一。例如對于聲明:

 

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

 

可以這樣分解:

 

typedef  int (*PARA)[5];

typedef PARA (*func)(int *);

 

這樣就容易看得多了。

 

typedef的另一個作用,是作為基于對象編程的高層抽象手段。在ADT中,它可以用來在C/C++和現(xiàn)實世界的物件間建立關聯(lián),將這些物件抽象成C/C++的類型系統(tǒng)。在設計ADT的時候,我們常常聲明某個指針的別名,例如:

 

typedef struct node * list;

 

ADT的角度看,這個聲明是再自然不過的事情,可以用list來定義一個列表。但從C/C++語法的角度來看,它其實是不符合C/C++聲明語法的邏輯的,它暴力地將指針聲明符從指針聲明器中分離出來,這會造成一些異于人們閱讀習慣的現(xiàn)象,考慮下面代碼:

 

const struct node *p1;

typedef struct node *list;

const list p2;

 

p1類型是const struct node*,那么p2呢?如果你以為就是把list簡單“代入”p2,然后得出p2類型也是const struct node*的結果,就大錯特錯了。p2的類型其實是struct node * const p2,那個const限定的是p2,不是node。造成這一奇異現(xiàn)象的原因是指針聲明器被分割,標準中規(guī)定:

 

6.7.5.1 Pointer declarators

 

Semantics

 

 If in the declaration ‘‘T D1’, D1 has the form

 

* type-qualifier-listopt D

 

and the type specified for ident in the declaration ‘‘T D’’ is

 

‘‘derived-declarator-type-list T’’

 

then the type specified for ident is

 

‘‘derived-declarator-type-list type-qualifier-list pointer to T’’

 

For each type qualifier in the list, ident is a so-qualified pointer.

 

指針的聲明器由指針聲明符*、可選的類型限定詞type-qualifier-listopt和標識符D組成,這三者在邏輯上是一個整體,構成一個完整的指針聲明器。這也是多個變量同列定義時指針聲明符必須緊跟標識符的原因,例如:

 

int *p, q, *k;

 

pk都是指針,但q不是,這是因為*p*k是一個整體指針聲明器,以表示聲明的是一個指針。編譯器會把指針聲明符左邊的類型包括其限定詞作為指針指向的實體的類型,右邊的限定詞限定被聲明的標識符。但現(xiàn)在typedef struct node *list硬生生把*從整個指針聲明器中分離出來,編譯器找不到*,會認為const list p2中的const是限定p2的,正因如此,p2的類型是node * const而不是const node*

 

雖然typedef struct node* list不符合聲明語法的邏輯,但基于typedefADT中的重要作用以及信息隱藏的要求,我們應該讓用戶這樣使用list A,而不是list *A,因此在ADT的設計中仍應使用上述typedef語法,但需要注意其帶來的不利影響。

posted on 2016-04-14 13:49 sheng 閱讀(258) 評論(0)  編輯 收藏 引用

導航

<2016年4月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

統(tǒng)計

常用鏈接

留言簿(1)

隨筆檔案

收藏夾

同行

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线视频日韩精品| 欧美成人亚洲| 亚洲免费伊人电影在线观看av| 欧美日韩一区二区在线| 在线亚洲一区观看| 亚洲视频你懂的| 国产亚洲激情| 欧美激情精品久久久久久蜜臀| 欧美精品国产| 午夜日韩电影| 久久手机精品视频| 一区二区电影免费观看| 亚洲欧美在线aaa| 曰本成人黄色| 一本久道久久久| 国语自产精品视频在线看8查询8| 久久久久久日产精品| 免费亚洲一区二区| 欧美一区免费| 欧美极品aⅴ影院| 久久精品日韩| 欧美日韩一区二区三区免费| 久久免费黄色| 欧美日韩精品久久久| 久久精品国产清自在天天线| 欧美电影在线播放| 久久国产精品72免费观看| 欧美激情亚洲激情| 久久久国产一区二区三区| 欧美精品麻豆| 玖玖视频精品| 国产精品视频第一区| 亚洲国产经典视频| 国产精品一区在线观看| 91久久久一线二线三线品牌| 国产视频精品免费播放| 日韩视频在线永久播放| 一区在线观看| 午夜电影亚洲| 亚洲欧美日韩另类| 欧美精品在线一区二区| 免费观看一级特黄欧美大片| 国产精品私拍pans大尺度在线 | 午夜视频一区| 欧美精品一区二区视频| 免费看精品久久片| 狠狠色综合播放一区二区| 国产精品99久久久久久白浆小说| 亚洲精品乱码久久久久久黑人| 欧美一区二区三区视频免费| 亚洲欧美成人一区二区在线电影| 国产午夜精品麻豆| 亚洲综合色激情五月| 欧美顶级大胆免费视频| 老司机67194精品线观看| 欧美少妇一区二区| 日韩亚洲欧美精品| 一本久久综合| 欧美日韩另类在线| 亚洲精品一区二区在线观看| 亚洲剧情一区二区| 欧美二区不卡| 91久久精品一区| 日韩亚洲精品在线| 欧美日韩国产一区二区三区| 亚洲七七久久综合桃花剧情介绍| 亚洲精品一区久久久久久| 美女图片一区二区| 亚洲日本欧美日韩高观看| 亚洲免费久久| 国产精品播放| 亚洲欧美文学| 另类天堂av| 亚洲高清av在线| 免费观看亚洲视频大全| 亚洲激情在线播放| 亚洲深夜福利视频| 国产精品一区二区三区乱码| 性欧美xxxx视频在线观看| 久久综合狠狠综合久久综青草 | 免费久久久一本精品久久区| 亚洲大片av| 亚洲视频欧美在线| 国产日本欧美一区二区三区| 久久激情五月婷婷| 欧美成人免费大片| 亚洲一区二区三区777| 国产精品自拍网站| 噜噜噜在线观看免费视频日韩| 亚洲精品久久久久久久久久久久| 亚洲欧美国产一区二区三区| 国产在线精品成人一区二区三区 | 国产精品亚发布| 久久久97精品| 夜夜爽av福利精品导航| 久久精品日产第一区二区| 亚洲激情电影中文字幕| 欧美午夜片欧美片在线观看| 久久成人免费日本黄色| 亚洲日本中文字幕免费在线不卡| 午夜在线成人av| 亚洲片在线观看| 国产精品一香蕉国产线看观看| 久久久夜色精品亚洲| 一区二区高清| 欧美91精品| 久久成人18免费网站| 日韩系列欧美系列| 国内精品美女av在线播放| 欧美日韩视频在线一区二区观看视频| 亚洲欧美一区二区激情| 亚洲精品视频在线看| 久久久精品2019中文字幕神马| 日韩西西人体444www| 在线观看欧美日本| 国产欧美一区二区三区国产幕精品| 欧美国产一区二区| 久久久最新网址| 亚洲激情婷婷| 欧美二区不卡| 久久gogo国模啪啪人体图| 伊人久久综合| 国产日韩一级二级三级| 欧美日韩在线播放一区| 免费亚洲电影在线| 久久久久久国产精品mv| 午夜精品视频网站| 亚洲一区免费| 在线亚洲一区| 一区二区三区毛片| 亚洲日本激情| 亚洲第一成人在线| 欧美成人自拍视频| 欧美高清视频一区二区| 毛片一区二区| 美日韩精品视频| 久久九九99| 久久久99国产精品免费| 欧美在线一区二区三区| 午夜在线观看欧美| 亚洲欧美精品中文字幕在线| 亚洲一区二区三区乱码aⅴ蜜桃女| 99re8这里有精品热视频免费 | 亚洲人在线视频| 亚洲国产精品久久精品怡红院 | 国产欧美日韩亚洲一区二区三区 | 久久久91精品国产一区二区三区| 午夜久久久久| 久久久久久黄| 欧美承认网站| 欧美日韩免费一区二区三区| 欧美三级精品| 国产精品一香蕉国产线看观看| 国产精品影音先锋| 好看的日韩av电影| 亚洲大片av| 亚洲免费观看高清在线观看 | 一本大道久久a久久精二百| 亚洲色图综合久久| 午夜精品久久一牛影视| 久久精品九九| 欧美激情成人在线视频| 日韩网站在线| 欧美一区2区三区4区公司二百| 久久久国产亚洲精品| 欧美激情麻豆| 国产精品尤物| 最新中文字幕亚洲| 午夜精品一区二区三区在线| 久久在线精品| 日韩天堂在线观看| 久久国产欧美| 欧美日韩精品免费观看视一区二区 | 老色鬼久久亚洲一区二区| 亚洲三级免费| 欧美在线日韩| 欧美日韩国产色视频| 国产日韩欧美视频| 亚洲精品免费电影| 久久激情五月丁香伊人| 亚洲国内在线| 欧美影院视频| 欧美日韩在线观看一区二区| 国内偷自视频区视频综合| 99亚洲视频| 男人插女人欧美| 亚洲直播在线一区| 欧美国产日韩一区二区| 亚洲欧洲日本在线| 激情久久五月| 宅男噜噜噜66一区二区| 麻豆91精品| 亚洲欧美在线免费| 欧美激情国产精品| 激情综合色丁香一区二区| 午夜久久黄色| 日韩一区二区电影网| 欧美国产欧美综合 | 欧美日韩综合在线免费观看| 亚洲国产精品999|