今天看了《c專家程式設計》裡的』分析c語言的宣告』一章,終於懂了c語言的複雜宣告是怎麼解析的。雖然在平時寫**的時候用到複雜宣告的情況幾乎沒有,這裡還是做乙個記錄,也是加深對c語言宣告的理解。
以下規則來自《c專家程式設計》。
c語言宣告的優先順序規則:
c. 如果const或volatile 關鍵字的後面緊跟型別說明符(如int,long等),那麼它作用於型別說明符。在其他情況下,const和volatile 關鍵字作用於它左邊緊鄰的指標星號。
通過上述規則畫出乙個神奇的宣告解析環:
看乙個例子:char *(*next)();
用優先順序規則來解讀一下:
- 找到它的名字,是next,注意到離next最近的是*
與()
- b1規則告訴我們()
優先順序最高,我們把括號裡的東西作為乙個整體,通過b3規則,我們得到next是乙個指標,指向***
- 考慮括號外面的東西。在*
與()
間作出選擇,b2優先於b3。所以next是乙個指標,指向乙個函式,它的返回值是***
- 然後,處理*
,得到next是乙個指標,指向乙個函式,它的返回值是乙個指標,指標指向***
- 最後,處理char
,得到next是乙個指標,指向乙個函式,它的返回值是乙個指標,指標指向char型別.
把上述結果總結一下就是:next是乙個指標,它指向乙個函式,該函式的返回值是乙個char型別的指標。
例子const char *str[10];
:
如果是char * const str[10];
:
- 找到名字,是str
- 處理,所以str是乙個陣列,它包含10個***
- 處理const
,根據c規則const修飾*,那麼str是乙個陣列,它包含了10個指向***的const指標
- 處理char
,next是乙個陣列,它包含了10個指向char型別的const指標
來乙個複雜一點的例子char *(* test[10])(int p)
:
typedef的功能是為乙個型別引入新的名字。當需要使用到複雜宣告的時候,使用typedef可以簡單宣告。典型的例子是signal()
原型的宣告。signal()
原型是一種系統呼叫,用於通知執行時系統有「軟體中斷」產生。
signal()
的宣告如下:void (*signal(int sig, void(*func)(int)))(int);
。運用上面的宣告解析,得到它的意思如下:
void (*signal( ))(int);
,signal是乙個函式,它返回乙個函式指標,後者所指向的函式接受乙個int引數並返回void。signal
有兩個引數,其中乙個恐怖的引數和返回值是同一型別:void (*func)(int)
。
上述宣告可以使用typedef來簡化,讓我們用typedef來表示通用部分:
/*
* 表示ptr_to_func是乙個函式指標,指向乙個引數為int,返回值為void的函式。
*/typedef
void (* ptr_to_func)(int);
/* * 表示signal是乙個函式,它接受兩個引數,乙個是int,乙個是ptr_to_func,返回值為ptr_to_func。
*/ptr_to_func signal(int, ptr_to_func);
C語言複雜宣告
專家程式設計 第三章介紹了如何分析複雜的宣告,講的非常不錯。對於作者介紹的分析複雜宣告的方法,我沒有完全掌握,不過,我有我自己的一套方法來解析複雜的宣告,正所謂條條大道通羅馬,只要結果一樣,必須在乎過程呢。今天在網上找了幾個複雜的宣告,練練手 宣告的例子全部來自網路,原諒出處未詳 記下此文,作個標記...
C語言複雜宣告
問題1 宣告與函式 void 0 讓我們從兩個不同的途徑來詳細分析這個問題。分析 首先,最基本的函式宣告 void function paramlist 最基本的函式呼叫 function paramlist 鑑於問題中的函式沒有引數,函式呼叫可簡化為 function 其次,根據問題描述,可以知道...
C語言複雜宣告
乙個宣告 int p 分為四部分 1 p 2 p右面的符號 可以什麼都沒有 3 p左面的符號 可以什麼都沒有 4 最左面的型別說明符 解讀乙個宣告先從p開始,然後的順序是 右左右左右左右左 看完了p,然後從p的右邊開始看符號 因為優先順序高的符號 和 是放在右邊的 如果有符號,就和p先結合。看完右邊...