簡體   English   中英

聲明符和直接聲明符有什么區別?

[英]What is the difference between a declarator and a direct-declarator?

在作者 Brian W. Kernighan 和 Dennis M. Ritchie的 C Programming Language, 2nd Edition 中,他們討論了聲明符和直接聲明符。 討論從本書第 1 頁開始。 122 with dcl and direct-dcl 's 請用通俗易懂的方式解釋聲明符和直接聲明符之間的區別好嗎? 是什么讓它變得直接

另外,在第 225

其中直接聲明符是標識符或帶括號的標識符。 特別是,它不能通過 typedef 實現 function 類型。

在我看來declarators就是一個變量的聲明或者function。在“TD”中,T部分指定了它的說明符和類型,D部分指定了identity,即變量的唯一標識名或者function。它有與語言的語法有關。

declarator是間接的,因為它們沒有像direct-declarator那樣被指定為直接的嗎?

如今,即使是第二版 K&R 也更具歷史意義而非實際意義。

盡管如此,術語“聲明符”和“直接聲明符”仍在當前的 C 語言規范中繼續使用。 語言規范這樣描述前者:

每個聲明符聲明一個標識符,並斷言當與聲明符形式相同的操作數出現在表達式中時,它指定一個 function 或 object,其中 scope、存儲持續時間和類型由聲明說明符指示。

(C17 6.7.6/2)

因此,“聲明說明符”與“聲明符”是分開的。 事實上,聲明符是聲明的一部分,它指定聲明的內容。

“直接聲明符”是聲明符的一個子集。 “直接”與指針中的“間接”形成對比。 例如,給定

int i;
int *p;

i*pp都是句法聲明符,但其中只有ip直接聲明符。 並且只有i*p完整的聲明符,它們不作為另一個聲明符的一部分出現(如聲明符p那樣)。

它變得比這更復雜——例如,將任何聲明符括在括號中會產生一個直接聲明符,即使就其本身而言,原始聲明符不是直接聲明符。

總的來說,這是一個語法上的區別,您可能不需要太擔心,除非您正在為 C 語言編寫解析器。 如果你這樣做,那么你真的需要查看正式的語法描述。

籠統地說,聲明符是一個完整的聲明,而直接聲明符要么是一個標識符本身,要么是一個標識符后跟[] (使其成為一個數組)或() (使其成為 function 或 function 指針)。

這些術語的完整定義可以在聲明符的語法中找到,聲明符可以在C11 標准的第 6.7.6p1 節中找到:

聲明符:

  • 指針選擇直接聲明符

直接聲明符:

  • 標識符
  • (聲明符)
  • 直接聲明符[類型限定符列表opt賦值表達式opt ]
  • 直接聲明符[ static類型限定符列表選擇賦值表達式]
  • 直接聲明符[類型限定符列表static賦值表達式]
  • 直接聲明符[類型限定符列表opt * ]
  • 直接聲明符(參數類型列表)
  • 直接聲明符(標識符列表選項)

指針:

  • *類型限定符列表選擇
  • *類型限定符列表選擇指針

類型限定符列表:

  • 類型限定符
  • 類型限定符列表 類型限定符

參數類型列表:

  • 參數列表
  • 參數列表, ...

參數列表:

  • 參數聲明
  • 參數列表,參數聲明

參數聲明:

  • 聲明說明符
  • 聲明說明符抽象聲明符選擇

該語法需要一個直接聲明符標記來指定優先級。 事實上, * foo [ 3 ]必須被解析為聲明*后跟一個直接聲明foo [ 3 ] 如果語法沒有將聲明符直接聲明符分開,則可能不清楚這是*后跟foo [ 3 ]組合在一起還是* foo后跟[ 3 ]組合在一起。

語法說聲明符是:

  • 指針選擇直接聲明符

其中指針*后跟可選的限定符(如const ),直接聲明符是以下之一:

  • 標識符
  • (聲明符)
  • 直接聲明符[類型限定符列表opt賦值表達式opt ]
  • 直接聲明[ static類型限定符列表選擇賦值表達式]
  • 直接聲明[類型限定符列表static賦值表達式]
  • 直接聲明符[類型限定符列表opt * ]
  • 直接聲明符(參數類型列表)
  • 直接聲明(標識符列表選項)

因此,給定* foo [ 3 ] ,我們必須將其作為聲明符, *表示指針foo [ 3 ]表示直接聲明符 無法在直接聲明符的開頭使用* 因此, * foo [ 3 ]必須聲明一個包含 3 個指針的數組,而不是指向包含 3 個元素的數組的指針。

如果將declaratordirect-declarator的那些選項合並為一個語法標記,那么解析就會有歧義。 您可以將其解析為* foo [ 3 ]因為* foo是一個后跟[ 3 ]的聲明符,這不是我們想要的。

名字並不重要; 我們只需要額外的令牌的另一個名稱。 在 C 語法中還有其他示例。 值得注意的是,表達式文法以表達式開始,然后經過一系列賦值表達式條件表達式邏輯或表達式等。 在您到達primary-expression之前,它們的名稱與它們涉及的運算符相關聯。 這與direct-declarator有一些語義相似性,表明它們都是本着“好的,我們到達了這個語法鏈的底部,這是主要/直接標記”的精神命名的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM