-1

我了解与运营商短路的基本概念,但为什么

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?

我知道已经有人问过类似的问题,但我不明白这个我在任何地方都找不到的具体例子。

4

3 回答 3

1
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
于 2020-11-13T19:45:21.333 回答
1

后缀自增运算符的值是其操作数在自增前的值。

所以表达式 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

于 2020-11-13T19:55:05.640 回答
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

于 2020-11-13T20:00:08.737 回答