理解C/C++語言的聲明文法-聲明子

來源:互聯網
上載者:User

這是理解C/C++語言的聲明文法系列的下半部分,繼續閱讀之前請先閱讀理解C/C++語言的聲明文法-聲明

一個聲明為每個聲明子都聲明一個實體(entity),同時為那個實體給出一個名字,並且隱含的給出儲存類,類型,和由說明符給出的其它特性。說明符和聲明子一起決定了名字是否是一個對象,數組,指標,引用或函數。例如,

聲明x為一個整型指標,f為一個函數返回一個整型。正是聲明子*x和f()使類型x和f產生區別。

int *x, f();

declarator: [ * [ const ] | & ]... direct-declarator

direct-declarator: declarator-id | ( declarator ) |

direct-declarator ( parameter-declaration-list ) |

direct-declarator [ constant-expression ]

A declarator-id is an identifier, possibly qualified:

declarator-id: [ nested-name-specifier ] identifier

nested-name-specifier: { class-or-namespace-name ::}...

如果聲明子是一個僅包含一個declarator-id的直接-聲明子,那麼這說明這個標識符具有decl-specifiers隱含的屬性,而沒有進一步的修飾。例如,在下面的聲明中

int n;

聲明子是n,這是一個只包含direct-declarator的declarator-id,因此根據含義,n的類型為整型。

如果聲明子為其它形式,那麼你可以按照下面的方法確定標識符的類型:首先,假設T為decl-specifiers隱含的類型,忽略friend或static等非類型屬性,同時假設D為聲明子。然後重複下面的步驟直到推匯出D為一個declarator-id,此時T正是你所尋找的類型:

1. 如果D形如(D1),那麼用D1替換D。

2. 如果D形如* D1 或 * const D1,那麼根據是否有const,用“指標,它指向T”或者“常量指標,它指向T”替換T,然後用D1替換D。

3. 如果D形如D1(參數-聲明-列表),那麼用參數由參數-聲明-列表定義的、“返回T的函數”替換T,然後用D1替換D。

4. 如果D形如D1[常量-運算式],那麼用元素個數由常量-運算式給出的“T數組”替換T,然後然後用D1替換D。

5. 最後,如果聲明子形如&D,那麼用“T引用”替換T,然後用D1替換D。

作為一個樣本,考慮下面的聲明

int *f();

首先,T和D分別為int和*f(),因此D形如*D1,其中D1為f()。

你可能認為D可以形如D1() 或者 *D1。然而,如果D形如D1(),那麼D1將不得不為*f,D1將是一個direct-declarator(因為本節開始處的文法注1規定只有direct-declarator前面是())。但是如果我們看看direct-declarator的定義注2,很明顯它不能包含*。因此,D只能是*f(),它形如*D1,其中D為f()。

既然我們已經確定D1為f(),那麼我們知道必須用“指標,它指向T”替換T,即“指標,指向整型”,同時用f()替換D。

至此我們還沒有解析D為declarator-id,因此我們必須重複該過程。此時,D1隻能是f,因此我們用“返回T的函數”替換T,它是一個“返回整型指標不帶參數的函數”,然後用f替換D。

此時,D為declarator-id,因此推導結束。我們已經確定聲明

int *f();

聲明f的類型為“不帶參數返回整型指標的函數”。另一個例子,聲明

int* p, q;

具有兩個聲明子,*p和q。對於每個聲明子,T都是int。對於第一個聲明子,D是*p,因此T變成“指標,它指向整型,”而D為p。聲明p類型為“指標,它指向整型”。

我們單獨分析第二個聲明子,T還是int,D是q。很明顯聲明q為整型。

最後,讓我們分析§10.1.2/173中那個奇怪的例子:

double (*get_analysis_ptr())(const vector<Student_info>&);

分析過程可以分為下面五個步驟

1. T: double    D: (*get_analysis_ptr())(const vector<Student_info>&)

2. T: 返回double帶有 const vector<Student_info>& 參數的函數    D: (*get_analysis_ptr())

3. T: function returning double... (如前所示)    D: *get_analysis_ptr()

4. T: 指標,它指向一個返回double...的函數    D: get_analysis_ptr()

5. T: 一個函數,返回一個函數指標,它指向一個返回double...的函數   D: get_analysis_ptr

get_analysis_ptr是一個函數,它返回一個函數指標,它指向一個返回double,帶有const vector<Student_info>&參數的函數。我們將如何展開const vector<Student_info>&作為一個練習。幸運的是,很少有函式宣告如此令人迷惑;它們中的大多數看起來

declarator: declarator-id ( parameter-declaration-list )

到目前為止,常見情況中最難的是返回函數指標的函數。

注1:這裡將allows翻譯為規定而不是允許。因為如果翻譯為允許,言外之意是()後面還可以是其它東西,但是在五條文法中找不到這種東西。文法指的是direct-declarator ( parameter-declaration-list )

注2:“declarator: [ * [ const ] | & ]... direct-declarator

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.