当“++ i&& ++ j”评估为真时,为什么“k = ++ i& ++ j || ++ k”语句中“k”不递增?

时间:2013-04-29 05:32:38

标签: c expression logical-operators

在逻辑运算符应用于结果之前,是否应首先计算复合逻辑 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

5 个答案:

答案 0 :(得分:6)

你应该避免编写这样不可读的代码。它实际上被解析为

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

因此,j >= 0 ++j条件始终为真,因此++k不会被评估,因为&&是一个简短的然后但是||是一个简短的或者(所以他们可能不会评估他们的右操作数)。

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

特别是,在编码if (x > 0 && 20/x < 5)时,永远不会尝试x==0

另请阅读维基百科operators in C & C++&amp; short circuit evaluation&amp; lazy evaluation页;请花几个小时阅读一本好的C编程书。

答案 1 :(得分:1)

逻辑运算符具有短路评估,即只要确定表达式的值,就不会评估表达式的其余部分。

e.g。 m = ++i && ++j || ++k; 在这个++ i - &gt;是的,++ j - &gt;真(非零值) 因此m = true && true || ++k;

现在正确&amp;&amp;的确如此 所以

m = true || ++k 

如在OR运算符中,如果1方为真,则另一方未评估,因此结果为真。

因此k不会增加。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

&&||是逻辑运算符,你正在使用它们的上下文,这是奇怪的(对于C / C ++来说没问题但你在Java或C#中有类型错误)。

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

答案 4 :(得分:0)

m = ++ i&amp;&amp; ++ j || ++ K表;

上面的代码行首先执行++ i和++ j,因为它是在||之后写的,所以不执行++ k (OR)

逻辑电路运算符在||的情况下,如果先前的语句为真,则不执行和&amp;&amp;

的情况下为假

因此k未受影响