分析C語言的宣告(2)
宣告器(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的指標。
相關文章
- Go 語言的詞法分析和語法分析(2)—Import宣告的解析Go詞法分析語法分析Import
- c語言的定義與宣告C語言
- 理解C語言宣告的優先順序規則C語言
- 【譯】Go語言宣告語法Go
- 標準C語言2C語言
- 高階C語言2C語言
- C語言作業2C語言
- 重新學C語言2C語言
- 簡易C語言文法分析C語言
- go語言 變數的宣告與使用Go變數
- C語言結構體大小分析C語言結構體
- C_Primer第2章 C語言概述C語言
- C語言進階[2]:字串常量C語言字串
- 週報2【C語言】【Web安全】C語言Web
- go語言變數的宣告與賦值Go變數賦值
- C語言宣告知識體系總結大學霸IT達人C語言
- C語言基礎-2、字元型別C語言字元型別
- C語言常見使用問題2C語言
- C語言與嵌入式C語言的區別C語言
- go語言與c語言的相互呼叫GoC語言
- GO語言—————7.1 宣告和初始化Go
- C語言C語言
- 聊聊C語言/C++—程式和程式語言C語言C++
- c語言中陣列的宣告與初始化C語言陣列
- c語言巨集的使用C語言
- 有用的C語言工具C語言
- c語言的基礎C語言
- C語言的函式C語言函式
- c語言的陣列C語言陣列
- 鴻蒙開發TypeScript語言:【變數宣告】鴻蒙TypeScript變數
- 安全宣告標記語言SAML2.0初探
- c語言是如何解析表示式語句"2+3*4;"的?C語言
- C語言基礎-2、函式的定義與使用C語言函式
- C語言的角落——這些C語言不常用的特性你知道嗎?C語言
- Python和C語言有什麼區別?分析!PythonC語言
- C語言:一種高效、易學的程式語言C語言
- Go語言的前景分析Go
- C語言字串C語言字串