例1:下面使用上述規則解讀這個聲明css
char* const *(*p[10])()
標識符爲p,p被一對括號包住,因此把括號裏面的東西看成一個總體來看,p的後綴是[],則p
是一個數組,p前面有一個星號,表示數組中的元素爲指針,(*p[10])後面緊跟着(),則表示
這是一個指向函數的指針,且該函數沒有參數,(*p[10])前面的緊挨着*,則表示該函數返 回一個指針,該指針指向一個類型爲char的常量指針.html
例2:下面使用上述規則解讀這個聲明git
void (*s(int sig,void(*func)(int)))(int);
標識符爲s,s被一對括號包住,因此將(*s(int sig,void(*func)(int)))做爲一個總體
分析,s後面緊跟着一對括號,則表示s是一個函數,s的第一個參數爲int,第二個參數是一個
函數指針,該函數指針指向一個參數爲int無返回值的函數;此時函數s的參數解讀完畢,那麼
剩下未解讀的部分都是s的返回值,s的左邊緊挨着*號,則表示s的返回值是一個指針,又由於
(*s(int sig,void(*func)(int)))後面緊跟着一對()則表示該指針爲函數指針,指向一個參數爲int無返回值的函數。github
使用該流程圖解析上述例1:web
剩餘的聲明 | 所採起的步驟 | 結果 |
---|---|---|
char* const *(*p[10])() | 第1步 | 表示"p是....",這裏先找出聲明中的表示符爲p |
char* const *(* [10])() | 第2步 | 表示"p是....的數組",這裏肯定p爲數組,接下來 要肯定數組p中的元素類型 |
char* const *(* )() | 第5步 | 表示數組元素類型爲"指向....的指針",接下來 要肯定指針的類型 |
char* const *( )() | 第4步 | *p[10]已經處理完成,去掉用來包裹他們的一對 括號 |
char* const * () | 第2步 | 不符合,轉到第3步 |
char* const * () | 第3步 | 表示"無參,返回....的函數",接下來肯定函數的 返回值類型 |
char* const * | 第5步 | 表示"指向....的指針" |
char* const | 第5步 | 表示"只讀" |
char* | 第5步 | 表示"....的指針" |
char | 第6步 | char |
把上面的解析串起來可推導出:p是一個數組,該數組元素爲指向無參並返回指向只讀字符類型的指針的函數。
其實上面描述並不容易理解,能夠這樣描述:p是一個數組,該數組元素爲函數指針, 指向函數
沒有參數,並返回一個指針,該指針指向只讀的字符類型指針json
上述的例2就不使用這種方法解讀了,太繁瑣了,建議使用優先級規則優先級規則解讀複雜聲明
3. 使用typedef簡化複雜聲明
使用typedef徹底能夠使上述聲明簡單易懂,對於char* const *(*p[10])()這個聲明,
由上面分析可知數組p中的元素類型爲函數指針,那麼能夠使用typedef爲函數指針取別名數組
typedef char*const* (*PFN)();
而後在定義指針數組:ruby
PFN fnAry[10];
那麼fnAry和p是等價的。bash
對於markdown
void (*s(int sig,void(*func)(int)))(int);
這個聲明,使用typedef簡化以下:
typedef void(*PFN1)(int); PFN1 s(int sig,PFN1 pfn);
能夠看出使用typedef後,聲明獲得了極大的簡化。