我了解与运营商短路的基本概念,但为什么
int i = 0, j = -1, k = 1, m;
m = !(i++ && ++j) || ++k;
printf("%d %d %d %d", i, j, k, m);
有 1 -1 1 1 作为输出?具体来说,为什么 j == -1 而不是 0?
我知道已经有人问过类似的问题,但我不明白这个我在任何地方都找不到的具体例子。
我了解与运营商短路的基本概念,但为什么
int i = 0, j = -1, k = 1, m;
m = !(i++ && ++j) || ++k;
printf("%d %d %d %d", i, j, k, m);
有 1 -1 1 1 作为输出?具体来说,为什么 j == -1 而不是 0?
我知道已经有人问过类似的问题,但我不明白这个我在任何地方都找不到的具体例子。
i = -1;
i++; // value of expression is -1
// side effect is changing i to 0
if (i++) ; // value of `i++` is zero; the if will not "trigger"
i = 0;
if (i++ && foo) ; // i++ has value of zero (false)
// so false && <anything> is false
// so foo is not evaluated
后缀自增运算符的值是其操作数在自增前的值。
所以表达式 i++ 的值等于 0,因为变量 i 被初始化为 0。
所以子表达式的值就是i++
这个表达式中0
的子++j
表达式
(i++ && ++j)
不求值,表达式本身的值为0
.
应用否定运算符
!(i++ && ++j)
你会得到1
(逻辑正确)。所以表达式的子++k
表达式
!(i++ && ++j) || ++k
不会被评估。
结果整个表达式的值等于1
分配给变量的值m
。
m = !(i++ && ++j) || ++k;
另一方面,正如一开始所指出的那样,表达式i++
被评估了。所以在这个语句之后i
将等于1
。
int i = 0, j = -1, k = 1, m;
!(i++ && ++j) || ++k;
==> 只会i++
被评估,j
不会k
被评估
假设我们正在替换变量的值,那么表达式如下所示。
!(0 && ++ -1) || ++1
第 1 步:
!(0 && ++ -1)
==> for &&
operator 如果左侧操作数为 False,则我们不需要检查右侧操作数,因此-1
不会递增,因此值j
将是-1
它本身。
因此之前的左侧表达式||
变为!(0)
第2步:
!(0) || ++1
now!(0)
将为 1 ,因此对于||
运算符,如果左侧操作数为 TRUE ,则无需转到右侧操作数,则++k
不会执行。
m = 1 || ++1
==>1
由于 onlyi++
被评估,它将其值更改为,1
因此输出为:1 -1 1 1