C語言中複雜聲明的解讀和簡化

  1. 使用聲明的優先級規則解讀聲明
    • 解讀一個C語言聲明,首先要找到聲明中的標識符,而後按照優先級次序依次讀取
    • 優先級從高到低一次是:
      • 聲明中被括號括起來的部分
      • 後綴操做符:()表示這是一個函數,[]表示這是一個數組
      • 前綴操做符:*表示這是一個指針
    • const關鍵字後緊跟着類型描述符則說明該const關鍵字做用於類型說明符,
      其它狀況則做用於const左邊緊鄰着第一個*號

例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. 使用以下方式解讀聲明
    C語言複雜聲明解讀_解碼環.png

使用該流程圖解析上述例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後,聲明獲得了極大的簡化。

相關文章
相關標籤/搜索