【问题标题】:C operator precedence, logical vs unary in a++ && b++ || ++cC 运算符优先级,a++ && b++ 中的逻辑与一元 || ++c
【发布时间】:2018-03-24 11:02:40
【问题描述】:

在下面的代码中,

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 operator-precedence


【解决方案1】:

请注意优先级评估顺序不是同一个概念。 &&|| 的特殊行为表明,如果不需要,则根本不评估右侧。优先级告诉您如果它被评估,将如何评估它。

换句话说,优先级有助于描述如何解析表达式。但它并没有直接说明如何评价它。优先级告诉我们,解析您询问的表达式的方法是:

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

但是当我们去评估这棵解析树时,&&|| 的短路行为告诉我们,如果左侧决定结果,我们不会沿着右侧走侧面并评估任何事情。在这种情况下,由于a++ && b++ 为真,|| 运算符知道其结果将为 1,因此它根本不会导致 c++ 部分被计算。

这也是为什么像这样的条件表达式

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

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

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


在评估优先级和顺序方面很容易产生错误的印象。当我们有这样的表达式时

1 + 2 * 3

我们总是说“* 的优先级高于+ 意味着乘法首先发生”。但是如果我们抛出一些函数调用,像这样:

f() + g() * h()

这三个函数中的哪一个会首先被调用?事实证明我们不知道。优先级并没有告诉我们这一点。编译器可以安排首先调用f(),即使最后需要它的结果。另见this answer

【讨论】:

  • 优秀的答案!请注意,如果 nsum 都是 intsum == INT_MINn == -1,则 if(n == 0 || sum / n == 0) 是不安全的。
猜你喜欢
  • 2015-01-04
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-06-20
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多