C运算符优先级,在++&&中是逻辑还是一元b ++ || ++ c [英] C operator precedence, logical vs unary in a++ && b++ || ++c

查看:90
本文介绍了C运算符优先级,在++&&中是逻辑还是一元b ++ || ++ c的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下代码中,

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

输出将为3,我得到该结果或求出第一个条件,将其视为1,然后不关心其他条件,但是在c中,一元运算符的优先级高于逻辑运算符,就像在数学中一样

2 * 3 + 3 * 4

我们将首先评估乘积,然后求和,以评估上述表达式,为什么c不这样做呢?首先评估所有一元运算符,然后评估逻辑?

解决方案

请认识到优先级评估顺序不同. &&||的特殊行为表示,如果不需要,则完全不评估右侧.优先级告诉您有关如何对其进行评估的信息.

以另一种方式表示,优先级有助于描述如何解析表达式.但这并没有直接说明如何对其进行评估.优先级告诉我们,解析您要查询的表达式的方式是:

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

但是当我们去评估这个解析树时,&&||的短路行为告诉我们,如果左侧确定结果,那么我们就不会下降一边评估任何东西.在这种情况下,由于a++ && b++为true,所以||运算符知道其结果将为1,因此根本不会导致对c++部分进行求值.

这也是为什么条件表达式之类的原因

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

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

是安全的.在p为NULL的情况下,第一个不会崩溃,也不会尝试访问*p.如果n为0,则第二个将不被0除.


很容易得到错误的印象,而忽略评估的优先级和顺序.当我们有类似

的表达式时

1 + 2 * 3

我们总是说诸如"*+更高的优先级意味着乘法首先发生"之类的事情.但是,如果我们抛出一些函数调用,就像这样:

f() + g() * h()

这三个函数中的哪个将首先被调用?事实证明,我们不知道.优先权并没有告诉我们.即使最后需要其结果,编译器也可以安排先调用f().另请参见此答案. /p>

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

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? 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 || operator knows that its result is going to be 1, so it doesn't cause the c++ part to be evaluated at all.

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. The second one will not divide by 0 if n is 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. See also this answer.

这篇关于C运算符优先级,在++&&中是逻辑还是一元b ++ || ++ c的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆