C語言難點專題 複雜的函式宣告

2021-05-22 01:05:26 字數 1708 閱讀 5454

類似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語言複雜宣告

專家程式設計 第三章介紹了如何分析複雜的宣告,講的非常不錯。對於作者介紹的分析複雜宣告的方法,我沒有完全掌握,不過,我有我自己的一套方法來解析複雜的宣告,正所謂條條大道通羅馬,只要結果一樣,必須在乎過程呢。今天在網上找了幾個複雜的宣告,練練手 宣告的例子全部來自網路,原諒出處未詳 記下此文,作個標記...