分析C語言的宣告(2)

weixin_33912445發表於2018-07-28
宣告器(declarator)

宣告器是所有宣告的核心,簡單的說,宣告器就是識別符號以及與它組合在一起的任何指標、函式括號、陣列下標等。
表: C語言中的宣告器(declarator)

數量 C語言中的名字 C語言中出現的形式
零個或多個 指標 下列形式之一:
*const volatile
*volatile
*
*const
*volatile const
有且只有一個 直接宣告器 下列形式之一:
識別符號
識別符號[下標]
識別符號(引數)
(宣告器)
零個或一個 初始化內容 = 初始值

一個宣告由下表所示的各個部分組成(並非所有的組合形式都是合法的,但這個表描述了我們進一步討論所用到的詞彙)。宣告確定了變數的基本型別以及初始值(如果有的話)。
表: C語言中的宣告

數量 C語言中的名字 C語言中出現的形式
至少一個型別說明符 型別說明符(type-specifier) void char short int long signed unsigned float double
結構說明符(struct-specifier)
列舉說明符(enum-specifier)
聯合說明符(union-specifier)
儲存型別(storage-class) extern static register
auto typedef
型別限定符(type-qualifier) const volatile
有且只有一個 宣告器(declarator) 參見上表定義
零個或多個 更多的宣告器 , 宣告器
一個 分號

讓我們看一下如果你使用這些部件來構造一個宣告,情況能夠複雜到什麼程度。同時要記住,在合法的宣告中存在限制條件。你不可以像下面那樣做:

  • 函式的返回值不能是一個函式,所以像foo()()這樣是非法的。
  • 函式的返回值不能是一個陣列,所以像foo()[]這樣是非法的。
  • 陣列裡不能有函式,所以像foo這樣是非法的。
    但像下面這樣則是合法的:
  • 函式的返回值允許是一個函式指標,如: int (*foo())()
  • 函式的返回值允許是一個指向陣列的指標,如:int (*foo())[]
  • 陣列裡面允許有函式指標,如 int (* foo[])()
  • 陣列裡面允許有其他陣列,所以你經常能看到int foo[][]
優先順序規則

要理解一個宣告,必須要懂得其中的優先順序規則。

  • A 宣告從它的名字開始讀取,然後按照優先順序順序依次讀取。
  • B 優先順序從高到低依次是:
    -------B. 1 宣告中被括號括起來的那部分
    -------B. 2 字尾操作符:
    --------------括號()表示這是一個函式,而
    --------------方括號[]表示這是一個陣列。
    -------B. 3 字首操作符:星號*表示“指向...的指標”
  • C 如果const和(或)volatile關鍵字的後面緊跟型別說明符(如int,long等),那麼它作用於型別說明符。在其他情況下,onst和(或)volatile關鍵字作用於它左邊緊鄰的指標星號。

用優先順序規則分析C語言的一例宣告:

char * const *(*next)();
  • A 首先,看變數名“next”,並注意到它直接被括號括住。
  • B. 1 所以先把括號裡面的東西作為一個整體,得出“next是一個指向...的指標”。
  • B 然後考慮括號外面的東西,在星號字首和括號字尾之間作出選擇。
  • B. 2 B. 2規則告訴我們優先順序較高的是右邊的函式括號,所以得出“next是一個函式指標,指向一個返回...的函式”。
  • B. 3 然後,處理字首“*”,得出指標所指的內容。
  • C 最後,把“char * const”解釋為指向字元的常量指標。

把上述分析結果加以概括,這個宣告表示“next是一個指標,它指向一個函式,該函式返回另一個指標,該指標指向一個型別為char的常量指標”。

一個更復雜的例子:

char *(* c[10]) (int **p);

1.c
變數名是c
2.c[10]
c是一個有10個元素的陣列。
3.(* c[10])
c是一個有10個元素的陣列,陣列的元素型別是指標,即c是指標陣列。
4.(* c[10]) (int **p);
陣列的元素指標指向函式,故指標的型別是函式指標。指向的函式接收的形參p為int型的指標的指標型別(二級指標)。
5.*(* c[10]) (int **p);
函式的返回值為一個指標。
6.char *(* c[10]) (int **p);
函式的返回值為一個指向char的指標。

概括的說便是:
c是一個陣列[0...9],它的元素型別是函式指標,其所指向的函式的形參p是int型的指標的指標型別,函式的返回值是一個指向char的指標。

相關文章