在C中使用关系运算符的前缀与后缀。运算符的关联性如何影响?

时间:2018-10-19 03:06:40

标签: c

根据关联性规则,++前缀是从右到左的关联,而后缀++是从左到右的关联。在下面的代码中,我尝试了这两个选项以及相关的(<)检查。但是我收到的答案似乎违反直觉。有人可以帮我清理一下吗?

在此声明中:

(++i < 5)

我希望

"++i"

首先要解释,因为它具有从右到左的关联性,并且比“ <”具有更高的优先级,然后是

"++i < 5" 

待解释。相反,情况恰恰相反。下面是我用来尝试的完整程序。

#include <stdio.h>

int main(){
    int i = 0, j = 0;
    while (++i < 5)
    {
        printf("%d ", i);
    }
    puts("");
    while (j++ < 5)
    {
        printf("%d ", j);
    }


    return 0;
}

我收到该程序的以下输出:

1 2 3 4
1 2 3 4 5

2 个答案:

答案 0 :(得分:2)

++i < 5中,确实首先评估了++i。我不知道您为什么认为这没有发生。

j++ < 5中,表达式j++的值也首先被求值,但是表达式的值是预先增加的值(该增加实际上可能会在稍后发生,但这是另一个故事)。 j++(++j - 1)非常相似。

答案 1 :(得分:2)

一元运算符的关联性是没有意义的,因为它们是一元运算符。根据定义,关联性是二进制运算符的功能。

通常将后缀运算符标记为右关联,将前缀运算符标记为左关联。毫无疑问,有这样的约定是有原因的,但是实际上这并不重要。 [注1]

无论如何,优先级与评估顺序并没有真正的关系。在f(a)+f(b)*f(c)中,对f的三个调用可以以任何顺序发生,并且f(a)可以在乘法之前或之后被调用。显然,必须先评估一个操作数,然后才能应用使用该操作数的运算符(短路运算符除外),但这仅与优先级成正比关系。优先级实际上只是告诉您,如果要使表达式变得明确,则必须在何处加上括号。

注释

  1. 如果您正在使用bison / yacc的优先级功能(如果没有使用,请忽略此注释),并且不想使用%prec PREFIX手动标记前缀产生式,那么您可以选择标记 all < / em>一元运算符为相同优先级的右关联。这将使后缀运算符比前缀运算符更紧密地绑定,这是通常的惯例。但是,将它们划分为不同的级别更为常见(我认为更明智),从而使优先级更加明确。具有多种语法(前缀/前缀-或前缀/后缀++)的运算符,则需要在其前缀版本上标上%prec。这都没有正式意义。