繁体   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