在讀《C專家編程》一書的第三章時,書中談到C語言的聲明問題,《C專家編程》這本書只有兩百多頁,卻花了一章的內容去闡述這個問題,足以看出這個問題的重要性,要想透徹理解C語言的聲明問題僅僅看書是遠遠不夠的,需要平時多實踐並大量閱讀別人寫的代碼。下面借鑒《C專家編程》書中的兩個例子來說說這個問題,以下很多內容是摘自《C專家編程》的第55頁-79頁。
在C語言中,聲明的形式和使用的形式相似,這種用法可能是C語言的獨創,K & R也承認"C語言聲明的語法有時候會帶來嚴重的問題"。C語言的聲明存在的最大問題是你無法以一種人們所習慣的自然方式從左到右閱讀一個聲明。下面看一個例子:
char * const *(*next)();
如果在第一眼就能看出這個聲明要表達的意思,那麼證明你的C語言功底已經到了一定的程度。《C專家編程》一書中給出的識別步驟為:
1)從變量名next開始,並注意到它直接被括號括住;
2)所以先把括號裡的東西作為一個整體,得出"next”是一個指向....的指針;
3)然後考慮括號外面的東西,在星號前綴和括號後綴之間做一個選擇;
4)根據C語言聲明的優先級規則(後面會給出),優先級較高的是右邊的函數括號,所以得出"next"是一個函數指針,指向一個返回...的函數;
5)然後,,處理前綴"*",得出指針所指的內容;
6)最後,把"char * const *"解釋為指向字符串的常量指針。
把上述結果加以概括,這個聲明表示"next是一個指針,它指向一個函數,這個函數返回另一個指針,該指針指向一個類型為char的常量指針"。這個問題便迎刃而解了.
下面再看一個例子:
char *(* c[10])(int **p);
首先,從變量名c開始,然後處理後綴"[]",表明c是一個數組,接著處理前綴"*",表示c是一個指針數組。然後處理後面的括號,表明數組c中的指針類型是指向一個函數的指針,並且這個函數的參數有且僅有一個:為指向指針的指針,該函數的返回值為一個指向字符串的指針。歸納在一起,為:
"c是一個數組[0...9],它的元素類型是函數指針,其所指向的函數返回值是一個指向字符串的指針,並且把一個指向指針的指針作為唯一的參數"。
以下是《C專家編程》一書中提到的C語言聲明的優先級規則,摘自第64頁。
作者 海 子