類似void(*signal(int, void(*)(int)))()的說明, 經典或者不經典的書籍, 都有過解讀, 《c專家程式設計中》, 設定了一套長長的解讀規則, 記住它恐怕絕非易事, 後面終於在《c traps and pitfalls》找到能讓人輕鬆的解釋。 下面個人對這方面的理解。 建議大家翻閱一下 書的2.1節
a. 型別
b. 表示式性質的宣告符號
看例子:
函式顯然是滿足上面的要求
float ff(); ff()是乙個宣告符號, 同樣, 是乙個表示式(解讀為:ff是乙個float型別的表示式, 並且是乙個函式, ff是乙個返回值型別為float的函式).
變數的例子: float f, *g; 可以寫成: float (f), ((*g)), 所以加括號後, 不難發現, 這是乙個表示式(f是乙個float型別的表示式, 並且是乙個變數, 結論為f是乙個float型別的變數; g是乙個float型別的表示式, 並且是乙個指標變數,結論為g為float型別的指標變數)
因此, 函式宣告和變數宣告沒有區別:
函式宣告的結果, 就是宣告了乙個具有某種型別的「變數」. 該「變數」的型別為函式返回型別, 名稱為函式的名稱。
廣義上,對函式的理解,實質就是乙個變數,這個變數,即函式的返回值。
舉兩個簡單例子:
float *g(), (*h)();
由於括號的優先順序結合規律高於*, 所以原式可以寫為:
float *(g()), ((*h))()
結合理解一和理解二, 對第乙個宣告:
讓ggg代替g(), 表示式變為: float *(ggg); 說明整個表示式是乙個float型別的指標, 這個表示式的名稱為ggg.
由於ggg == g(), 這是乙個函式, 所以整個表示式為: g是乙個返回float指標型別的表示式, 並且為函式。===》g為乙個返回float指標型別的函式。
對於第二個宣告:
讓hhh代替*h, 表示式變為: float hhh(): 說明整個表示式是乙個float型別的表示式, 並且名稱為乙個函式.
由於hhh == *h , 既然hhh為乙個函式表示式, 則h必定是函式指標。==》h是乙個函式指標. 返回值為float型別
上述例子中, float (*h)(); 粗曠的型別定義為浮點表示式(float s, s==(*h)()), 細節的型別定義為引數為void函式, 返回為float(float s(), s = *h ); 再細節的定義為函式指標float (*h)();
這些定義完全是從理解的角度來劃分層次的。 這種劃分是要看對定義理解的幫助。
下邊的例子, 劃分的層次需要粗曠, 原因是較複雜。
void(*signal(int, void(*)(int)))(int)
粗曠劃分:
void (*fff)(int) 表示式返回為函式指標
表示式為乙個函式: signal(int, void(*)(int))
這個層次上的理解是對我們最有幫助的, 解釋為: 表示式返回了乙個函式指標, 這個表達是為乙個函式表示式。
當然如果你要這樣理解:
void (fff)(int) 表示式返回為函式指標
表示式為乙個函式: *signal(int, void(*)(int))
完全是個人喜好, 進一步劃分, 可以按照巢狀遞迴原則, 將其剝落出來.
C語言難點專題 預定義
c 語言型別定義粗略分為兩塊 第一 符號替換型別 define 第二 型別替換 typedef 第一種致命 是無所不能的代替作用,這裡是裸替,直接替換,比如章子怡同學不願被剝光,就請邵小珊同學裸替一下,技術含量相當不高,乙個肉身替換為另乙個肉身。include define globalvalue ...
C語言難點專題 陣列和指標
陣列和指標是c中常見的資料結構,和基本型別不同,這兩個資料結構可以表示多個資料的集合。在理解和區分這兩個概念前,先了解一下記憶體模型。記憶體就相當於街道兩邊的房子,記憶體位址,就是房子的門牌號。記憶體和房子一樣,可以存放需要的資料。現在問題就來了,怎麼描述一排排的房子 記憶體資料 呢?這裡有兩個方案...
C語言複雜宣告
專家程式設計 第三章介紹了如何分析複雜的宣告,講的非常不錯。對於作者介紹的分析複雜宣告的方法,我沒有完全掌握,不過,我有我自己的一套方法來解析複雜的宣告,正所謂條條大道通羅馬,只要結果一樣,必須在乎過程呢。今天在網上找了幾個複雜的宣告,練練手 宣告的例子全部來自網路,原諒出處未詳 記下此文,作個標記...