-1

在将逻辑运算符应用于其结果之前,复合逻辑AND/OR表达式中的各个表达式不应该首先被求值吗?为什么在以下程序++k的条件中保持不变:m = ++i && ++j || ++k

 #include<stdio.h>

 int main()
 {
      int i=-3, j=2, k=0, m;
    m = ++i && ++j || ++k;
    printf("%d, %d, %d, %d\n", i, j, k, m);
    return 0;
}

输出: -2,3,0,1

但我期望输出-2,3,1,1

4

5 回答 5

6

您应该避免编写此类不可读的代码。它实际上被解析为

m = (++i && ++j) || ++k;

因此,一旦j >= 0条件++j始终为真,++k则不会评估,因为是&&捷径,然后||是捷径,否则(因此他们可能不会评估其正确的操作数)。

所以&&计算如下:左操作数被计算,如果为假则返回,然后只有当它为真(即不等于0)时,右操作数被计算并作为 的计算结果返回&&。同样||评估如下:评估左操作数。如果它为真(非零),它将成为||;的结果 否则正确的操作数被评估并且是||表达式的结果。

特别是,在编码时if (x > 0 && 20/x < 5)从不尝试除法x==0

另请阅读C 和 C++以及短路评估惰性评估页面中的维基百科运算符;请花几个小时阅读一本好的 C 编程书籍。

于 2013-04-29T05:35:21.160 回答
1

逻辑运算符具有短路求值,即一旦为表达式确定了一个值,就不会对表达式的其余部分进行求值。

例如 m = ++i && ++j || ++k; 在这个 ++i -> true, ++j -> true (非零值) 因此m = true && true || ++k;

现在为真 && 真为真所以

m = true || ++k 

与 OR 运算符一样,如果一侧为真,则不评估另一侧,因此结果为真。

因此 k 不会增加。

于 2013-04-29T05:37:21.810 回答
0

这是逻辑运算符的快捷方式,在您的情况下为 operator ||。当第一个操作数为true时,第二个操作数不可能对结果产生任何影响。无论第二个操作数产生什么,它总是正确的。所以第二个操作数不被评估。

如果发现第一个操作数是 ,则逻辑&&运算符也是如此false。第二个操作数无关紧要,结果总是如此false,因此不会评估第二个操作数。

于 2013-04-29T05:35:30.313 回答
0

&&并且||是逻辑运算符,并且您在上下文之外使用它们,这很奇怪(对于 C/C++ 可以,但在 Java 或 C# 中会出现类型错误)。

您刚刚发现了短路运算符 - 如果您“知道”它是真的,则不需要评估整个表达式。即 i 和 j 不为零,因此您不需要对 k 做任何事情,因为您知道表达式为真。

于 2013-04-29T05:36:09.913 回答
0

m = ++i && ++j || ++k;

上面的代码行首先执行 ++i 和 ++j 并且不执行 ++k 因为它写在 || 之后 (或者)

在 || 的情况下,当先前的语句已经为真时,逻辑电路运算符不执行 如果是 && 则为 false

因此 k 未被触及

于 2013-04-29T05:40:49.383 回答