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

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

  #include 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

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

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

所以一旦j >= 0++j条件总是为真,所以++k不被计算,因为&&是一个短切,然后是 || 是一个短路或其他 (因此他们可能不会评估他们的正确操作数)。

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

特别是,当编码if (x > 0 && 20/x < 5) ,从不尝试对x==0进行除法。

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

逻辑运算符具有短路评估,即,一旦确定表达式的值,则不评估表达式的其余部分。

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

现在是真的&& true是如此

 m = true || ++k 

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

因此k不递增。

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

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

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

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

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

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

在||的情况下,当先前的语句为真时,逻辑电路操作符不执行 在&&的情况下为false

因此k是不受影响的