我了解与运营商短路的基本概念,但为什么
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