简体   繁体   English

C运算符优先级,a ++ && b ++ ||中的逻辑vs一元 ++ c

[英]C operator precedence, logical vs unary in a++ && b++ || ++c

In the follwing code, 在下面的代码中,

int a = 1, b = 2, c = 3, d;
d = a++ && b++ || c++;
printf("%d\n", c);

The output will be 3 and I get that or evaluates first condition, sees it as 1 and then doesn't care about the other condition but in c, unary operators have a higher precedence than logical operators and like in maths 输出将为3,我得到该结果或求出第一个条件,将其视为1,然后不关心其他条件,但是在c中,一元运算符的优先级高于逻辑运算符,例如在数学中

2 * 3 + 3 * 4

we would evaluate the above expression by first evaluating product and then the summation, why doesn't c do the same? 我们将先评估乘积,然后求和,以评估上述表达式,为什么c不会这样做呢? First evaluate all the unary operators, and then the logical thing? 首先评估所有一元运算符,然后再进行逻辑运算?

Please realize that precedence is not the same concept as order of evaluation . 请意识到, 优先级 与评估顺序不是同一概念。 The special behavior of && and || &&||的特殊行为 says that the right-hand side is not evaluated at all if it doesn't have to be. 说,如果不必对右侧完全不进行评估。 Precedence tells you something about how it would be evaluated if it were evaluated. 优先级告诉您有关如何对其进行评估的信息。

Stated another way, precedence helps describe how to parse an expression. 换句话说,优先级有助于描述如何解析表达式。 But it does not directly say how to evaluate it. 但这并没有直接说明如何评估它。 Precedence tells us that the way to parse the expression you asked about is: 优先级告诉我们,解析所要求的表达式的方式是:

      ||
      / \
     /   \
    &&   c++
   / \
  /   \
a++    b++

But then when we go to evaluate this parse tree, the short-circuiting behavior of && and || 但是,当我们评估此解析树时, &&||的短路行为 tells us that if the left-hand side determines the outcome, we don't go down the right-hand side and evaluate anything at all. 告诉我们,如果由左手确定结果,那么我们就不会沿右手进行任何评估。 In this case, since a++ && b++ is true, the || 在这种情况下,由于a++ && b++是true,因此|| operator knows that its result is going to be 1, so it doesn't cause the c++ part to be evaluated at all. 运算符知道其结果将为1,因此它根本不会导致对c++部分的求值。

That's also why conditional expressions like 这就是为什么条件表达式像

if(p != NULL && *p != '\0')

and

if(n == 0 || sum / n == 0)

are safe. 很安全 The first one will not crash, will not attempt to access *p , in the case where p is NULL. p为NULL的情况下,第一个不会崩溃,也不会尝试访问*p The second one will not divide by 0 if n is 0. 如果n为0,第二个将不除以0。


It's very easy to get the wrong impression abut precedence and order of evaluation. 容易获得错误的印象,而忽略评估的优先级和顺序。 When we have an expression like 当我们有一个像

1 + 2 * 3

we always say things like "the higher precedence of * over + means that the multiplication happens first". 我们总是说诸如“ *高于+的更高优先级意味着乘法首先发生”之类的话。 But what if we throw in some function calls, like this: 但是,如果我们抛出一些函数调用,例如:

f() + g() * h()

Which of those three functions is going to get called first? 这三个函数中的哪个将首先被调用? It turns out we have no idea. 事实证明,我们不知道。 Precedence doesn't tell us that. 优先权并没有告诉我们。 The compiler could arrange to call f() first, even though its result is needed last. 即使最后需要其结果,编译器也可以安排先调用f() See also this answer . 另请参阅此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM