2

在 C 中计算后缀表达式时,如果我们的标记是一个运算符,我们必须将其放入堆栈中,使其具有最高优先级。

我的问题是运算符*, /, %, 具有最高优先级。

我们是否也需要考虑关联性?由于所有这些运算符都具有 LEFT-TO-RIGHT关联性,是否会/获得更高的偏好*

4

3 回答 3

7

优先级通常只适用于中缀符号。后缀(和前缀)符号通常被认为是明确指定哪些操作数与哪个运算符相关联。只有在解析中存在歧义时,优先级才会发挥作用,而在后缀表示法中则不然。

中缀表达式中出现的优先级问题

4 * 5 + 3 / 12

转换为 RPN 表单后根本不存在

4 5 * 3 + 12 /

或前缀形式

(/ (+ (* 4 5) 3) 12)

.

在考虑诸如Shunting-Yard 算法之类的东西时,可能会产生混淆,该算法可用于从或直接评估中缀表达式生成 RPN 表示。它通过将运算符延迟到辅助堆栈上来处理运算符优先级,直到较低优先级的运算符强制它被弹出和评估(或输出)。

于 2013-08-21T04:47:50.857 回答
3

运算符 *, /, 的优先级%相同,并且关联性是从左到右的。所以像这样的表达式:

a * b / c            /* both operators have same precedence  */

等同于:

(a * b) / c

类似的表达式如下:

a / b * c            /* both operators have same precedence  */

等同于:

( a / b ) * c

因此,即使运算符的优先级相同,但假设它们出现在表达式中(不带括号),那么由于从左到右的关联性,最左边的运算符具有更高的优先级。

注意从概念上讲,我们在表达式中使用括号来覆盖运算符的优先级,因此虽然 expression: a / b * c与: 相同,(a / b) * c 但我们可以通过将 expression 写为 来强制*首先使用。如果您在编写代码时对运算符优先级有混淆,我的意思是使用括号。( )a / ( b * c)

编辑:

在 POSTFIX 和 PREFIX 形式中不要使用括号( )。运算符的优先级是按照表达式中出现的顺序决定的,因此在评估表达式时,它不需要搜索下一个操作来执行 - 因此评估变得很快

而在 INFIX 表达式中,运算符的优先级可以被括号覆盖( )。因此,中缀表达式中有括号——它需要搜索接下来要执行的操作,例如 a + b % d——并且表达式的评估很
这就是转换在计算机科学中有用的原因。

因此编译器首先将中缀表达式转换为等效的后缀形式(使用语法规则),然后生成目标代码来评估表达式值。这就是我们研究后缀和前缀形式的原因。

并且根据优先级和关联性规则,以下表达式:

a * b / c            /* both operators have same precedence  */

将被翻译成:

a b * c / 

和表达

a / b * c            /* both operators have same precedence  */

将被翻译成

a b / c *
于 2013-08-21T04:47:17.417 回答
0

我的问题是运算符*, /, %, 具有最高优先级。

它们是相等的,就像+-(binary) 相等一样。

我们是否也需要考虑关联性?

是的,例如1 + 2 + 3需要变成(1 + 2) + 3,即1, 2, ADD, 3, ADD,相对于1, 2, 3, ADD, ADD.

由于所有这些运算符都具有从左到右的关联性,因此 / 会获得比 * 更高的偏好吗?

关联性与优先级没有任何关系。这个问题没有意义。

但是如果你只是计算一个现有的 RPN 表达式,正如你的标题所说,我不知道你为什么要问这个。您只需推送操作数并在操作符出现时对其进行评估。你真的在问翻译RPN 吗?

于 2013-08-21T04:46:27.853 回答