怎麼理解C語言的複雜聲明?
cdecl: C gibberish ? English
char (*(*X())[]) ()
X是一個函數,返回值是一個指針,該指針指向一個數組,數組裡的元素是函數指針,這些函數指針所指向的函數的返回值是char類型。
X是一個3個元素的數組,數組裡的元素是函數指針,這些函數指針所指向的函數的返回值也是指針,該指針指向一個有5個char類型元素的數組。
char (*(*X[3])())[5]
C語言指針的複雜類型說明
這是我在CSDN上的一篇文章 不敢賣弄 希望能夠解決你的問題從未知量開始,一直推理到已知量。
例子1:char (*comp)()例子2:char (*(*X())[]) ()
- (*comp) comp解引用,這說明comp是個指針
- (*comp)() comp解引用後調用,這說明comp是個函數指針
- char (*comp)() comp解引用後調用的返回值是char,這說明comp是個返回值為char的函數指針
- X() X調用,這說明X是個函數
- (*X()) X調用的返回值解引用,這說明X是個返回值為指針的函數
- 現在X是什麼已經清楚了,現在的關鍵是其返回值的類型(用P表示)。
- (*X())[]P解引用後可以用[]運算,這說明P解引用後還是個指針
- (*(*X())[]) P解引用後用[]運算之後的值還可以用*運算,這說明P解引用後再解引用還是個指針
- (*(*X())[]) () P解引用後用[]運算之後再用*運算後可以調用,這說明P三次解引用後是一個函數
- char (*(*X())[]) () 該函數返回一個char
- 總結: X是個返回值為指針的函數,該指針解引用三次後是一個返回值為char的函數。
很多人認為 C 的類型聲明不直觀,然而如果不直觀為什麼 KR 要如此設計?實際上 C 的聲明其實很好理解的:
char (*(*X[3])())[5]
的含義就是:「(*(*X[3-1])())[5-1]」 的類型是 char。
或者說,變數聲明
T E&
的含義是把有關變數 x 的表達式 E 的類型聲明為 T。
腦力激蕩下可以,實際中誰要是寫出來這種你可以使勁扇他。
完全應當這樣:
typedef char* (*func_t) ();
typedef func_t** (*func2_t) ();
Clockwise/Spiral Rule不知道有沒有中文翻譯……
題主知道&不? 就是C老爹寫的那本. 在5.12節, 複雜聲明中有講解的.
- 解釋了怎麼讀
- 直接放大招, 做了一個 @坡下碎石 所說的那個網站的功能. dcl
- 大招裡面還有個叫undcl. 看名字就應該猜到了
Source: Reading C type declarations
如果讀C類型聲明可以理解為漸進演算法的話:
輸入: C語言的類型聲明, 例如: int **pi[5];
輸出: 英文的C類型聲明解釋(由於語言語言, 中文讀C類型聲明非常不友好), 例如: pi is an Array of 5 Pointer to Pointer to int.
演算法: (過於抽象的話, 後面有例子...)
I. 首先記住下面的規則:
i. 一個聲明&>&>必須&<&<擁有一個基本類型(basic type), 這個基本類型&>&>總是&<&<在類型聲明表達式的最左邊. 然而一個聲明可以具有&>&>0或更多&<&<個導出類型(derived type). (基本類型表請參照源鏈接) ii. 導出類型由三個操作符(operator)構建: i). *: 譯為 pointer to, 切記介詞to不可省略. ii). [x]: 譯為 array of, 切記介詞of不可省略. (e.g. int ai[5]: ai is array of 5 int)iii). ( ): 譯為 function returning. 這裡的小括弧(parentheses)指的是構成函數指針的小括弧而不是規定優先順序的小括弧. 區別: 構成函數指針的小括弧永遠出現在變數名的右邊,而規定優先順序的小括弧永遠將變數名包在裡面.
iv). ii)中的三個操作符的優先順序為: [x] 和( ) 優於*.II. 首先由變數名以及處於最左邊的基本類型構成不完整的解釋. 然後從變數名開始由內向外解釋聲明, 遵從"能向右解讀就向右解讀, 必須向左解讀時再向左解讀".Example: 就用提問里第二個 char (*(*x( ))[ ]) ( ); 解釋上面的演算法:
Step 1: (首先由變數名以及處於最左邊的基本類型構成不完整的解釋.): x is ... char. 下面逐步在"..."處增添關於x的解釋.
Step 2: (由於( ) 的優先順序高於*, 向右解讀): x( ): x is a function returning ... char.Step 3: (遇到右括弧, 向左解讀): *x( ): x is a function returning pointer to ... char.Step 4: (由於[ ] 優先順序高於*, 向右解讀): (*x( ))[ ]: x is a function returning pointer to array of ... char.Step 5: (遇到右括弧, 向左解讀): *(*x( ))[ ]: x is a function returning pointer to array of pointers to ... char.Step 6: (最後的右邊的括弧): (*(*x( ))[ ]) ( ): x is a function returning pointer to array of pointers to function returning char.
結果和cdecl的輸出一致.
原文圖文並茂還寫了很多其他的注意事項...
個人覺得沒意義。大牛秀智商?反被聰明誤吧。代碼就是為了簡化得人易理解,或者說在合作中更高效率理解別人的代碼。只是實現邏輯複雜沒辦法最簡也這麼複雜。
3,這是3個元素數組,裡面放的是指針,指針的類型一個函數(指針),這個函數的參數為空,返回值一個指針,指向5個char元素的數組!
推薦閱讀:
※C語言中的指針為什麼要區別出指向不同數據類型的指針?
※怎樣判斷浮點數是否相等並保證同一性?
※對於一個很複雜的常量表達式,編譯器會算出結果再編譯嗎?
※面向對象和面向過程分別是什麼?
※C C++ Python哪個更適合新手?