• <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>
            隨筆 - 0  文章 - 0  trackbacks - 0
            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿

            文章檔案(4)

            c 相關

            friends

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 782
            • 排名 - 2475

            最新隨筆

            最新評論

            因為C語言所有復雜的指針聲明,都是由各種聲明嵌套構成的。如何解讀復雜指針聲明呢?右左法則是一個既著名又常用的方法。不過,右左法則其實并不是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.


            ?這段英文的翻譯如下:

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

            ?func是一個返回值為具有5個int元素的數組的函數。但C語言的函數返回值不能為數組,這是因為如果允許函數返回值為數組,那么接收這個數組的內容的東西,也必須是一個數組,但C語言的數組名是一個右值,它不能作為左值來接收另一個數組,因此函數返回值不能為數組。

            ?int?func[5](void);

            ?func是一個具有5個元素的數組,這個數組的元素都是函數。這也是非法的,因為數組的元素除了類型必須一樣外,每個元素所占用的內存空間也必須相同,顯然函數是無法達到這個要求的,即使函數的類型一樣,但函數所占用的空間通常是不相同的。

            ?????????作為練習,下面列幾個復雜指針聲明給讀者自己來解析。

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

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

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

            ?????????實際當中,需要聲明一個復雜指針時,如果把整個聲明寫成上面所示的形式,對程序可讀性是一大損害。應該用typedef來對聲明逐層分解,增強可讀性,例如對于聲明:

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

            ?可以這樣分解:

            ?typedef??int?(*PARA)[5];
            ?typedef?PARA?(*func)(int?*);

            ?這樣就容易看得多了。?
            ??

            ??

            ?答案,同時給出用typedef的分解方法:


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

            ?func是一個指向數組的指針,這類數組的元素是一個具有5X6個int元素的二維數組,而這個二維數組的元素又是一個二維數組。

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


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

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

            ?typedef?int?(*PARA1)(int*);
            ?typedef?PARA1?(*PARA2)[5];
            ?typedef?PARA2?(*func)(int*);

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

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

            ?typedef?int?(*PARA1)[5];
            ?typedef?PARA1?(*PARA2)(int*);
            ?typedef?PARA2?func[7][8][9];


            ?

            posted on 2006-10-26 20:21 天性如此 閱讀(72) 評論(0)  編輯 收藏 引用
            精品一久久香蕉国产线看播放| 亚洲中文字幕无码久久精品1| 国产三级久久久精品麻豆三级| 亚洲中文字幕久久精品无码喷水| 一本色道久久88精品综合| 国产婷婷成人久久Av免费高清| 99久久免费只有精品国产| 亚洲欧美一级久久精品| 久久无码人妻一区二区三区| 国产精品综合久久第一页| 亚洲精品无码久久久久| 国产精品亚洲综合专区片高清久久久 | 一本大道加勒比久久综合| 天天综合久久一二三区| 久久ZYZ资源站无码中文动漫| 久久久久久久久久免免费精品| 伊人久久大香线焦AV综合影院 | 奇米综合四色77777久久| 国产精品美女久久久久AV福利| 亚洲伊人久久精品影院| 久久久久久噜噜精品免费直播| 成人资源影音先锋久久资源网| 久久综合久久鬼色| 久久久WWW成人| 9191精品国产免费久久| 国产91色综合久久免费| 午夜天堂av天堂久久久| 久久天天躁狠狠躁夜夜avapp| 狠狠人妻久久久久久综合| 亚洲午夜久久久精品影院| 国产一区二区精品久久| 国产精品美女久久久m| 人妻少妇久久中文字幕| 久久这里都是精品| 伊人久久大香线蕉AV一区二区| 久久精品无码一区二区三区免费| 色综合色天天久久婷婷基地| 精品久久久久中文字幕日本| www.久久热| 久久99热这里只有精品国产| 国产高潮国产高潮久久久91 |