【问题标题】:A question about precedence and associativity in C关于 C 中的优先级和关联性的问题
【发布时间】:2021-03-17 07:07:07
【问题描述】:

我有一个我无法理解的问题。

由于空格删除是C 编译过程的一部分,那么 C 编译器如何区分以下内容:

案例1:

int x = 2,y=4;
int z = x+++y;
printf("%d", z);//gives 6

案例 2:

 int x = 2,y=4;
 int z = x+ ++y;
 printf("%d", z);//gives 7

注意我在x+ 之后添加的空格,使++ 坚持y 而不是x,但是如果删除空格会发生这种情况?

【问题讨论】:

  • 但是你的问题有点误导,好像你对优先级和关联性有混淆,而不是在表达式评估中如何区分空格

标签: c compilation operator-keyword operator-precedence


【解决方案1】:

C 有一个贪心的从左到右的词法分析器:

http://port70.net/~nsz/c/c11/n1570.html#6.4p4:

如果输入流已被解析为预处理标记,直到 给定字符,下一个预处理标记是最长的序列 可以构成预处理标记的字符数。

...

所以+++ 必须被识别为++ + 而绝不是+ ++

然后,优先级和关联性决定 +++ 令牌如何绑定 (http://port70.net/~nsz/c/c11/n1570.html#A.2.1)。

简单地说,后缀运算符比前缀运算符绑定更紧密,前缀运算符比二元运算符绑定更紧密。所以x++ + y 表示(x++) + (y) 而绝不是(x) (++(+(x))(由于其他原因,这将是荒谬的)(例如,&x->member 表示&(x->member) 而不是(&x)->member),但这里的混乱似乎只在于如何片段被标记化。

【讨论】:

  • 您提供的页面中的这个示例“程序片段 x+++++y 被解析为 x ++ ++ + y,这违反了对增量运算符的约束”非常清楚这点可以理解,非常感谢!
【解决方案2】:

好吧,词法分析器并没有完全忽略空格,它负责获取标记并将它们传递给解析器。

在第一种情况下,词法分析器找到标记x+++y,而在第二种情况下,x+++、@词法分析器找到了 987654328@。

因此,与词法分析器解释源代码的方式相比,运算符优先级(保持不变)不是问题。

@PSkocik 提供了一个很好的参考。

为了澄清非计算机科学专业的毕业生,令牌是表示语言实体的字符序列,例如变量、运算符、关键字(if、while、for、int、float...)

【讨论】:

  • 我有一个问题,那么词法分析器步骤/标记化是否发生在空白删除步骤之前?
  • 词法分析器决定如何解释空格并确定是否以及如何使用它们来分隔标记。因此,这不仅仅是删除空格的简单规则。
  • 不是之前也不是之后。词法分析器被告知跳过任何空白作为单独的规则。它很可能被实现为不执行任何操作且不为其创建输出令牌的规则。
猜你喜欢
  • 2012-01-02
  • 2020-10-20
  • 2012-08-13
  • 1970-01-01
  • 2021-07-20
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多