我在下面给出的程序中输出为0..0。为什么在检查条件时j不会增加?
int main(int argc, char const *argv[])
{
int i=0,j=0;
if(i&&j++)
printf("%d..%d",i++,j);
printf("%d..%d",i,j);
return 0;
}
答案 0 :(得分:8)
由于i
为零,if
的后半部分不需要进行评估,因此j++
永远不会发生。
答案 1 :(得分:1)
post -increment,毫不奇怪,只会在语句之后发生,并且只有如果表达式的那部分是评价。
不要忘记&&
右侧的条件仅在左侧通过时才会被评估。该语句的j++
部分永远不会被评估,因为i
是0
。
您的代码大致转化为:
if (i) { // Always 0, so the inner block is skipped.
if (j) {
j = j + 1;
// ...
}
else {
j = j + 1;
}
}
如果这些操作混乱,可以完全避开它们。即使是经验丰富的程序员也可能会被绊倒。当你假设太多并且编写像j + j++
这样的代码时,你最终会遇到麻烦。
答案 2 :(得分:1)
声明中:
if(i&&j++)
我的值为0,所以即使j是预先递增的,也不会被评估。和&&和||运营商短路,即一旦得知答案,他们就会退出。我的情况是&&在||的情况下,左侧评估为零它是评估非零的左侧。
答案 3 :(得分:0)
涉及逻辑AND运算符的表达式可以重写如下:
if(expr1 && expr2 && expr3 ...)
在功能上等同于
if(expr1)
if(expr2)
if(expr3)
.
.
.
如果expr1
失败,则不会评估其余内容。
如果expr1
成功,则会评估expr2
,如果expr2
失败,则expr3
将无法评估。
在您的情况下,i
为零,因此j++
不会被评估。
摘自第6.5.13节 C99规范
与按位二进制&操作员,&&运营商保证从左到右的评估;之后有一个序列点 第一个操作数的评估。如果第一个操作数比较 等于0,不评估第二个操作数。