C中的具体短路示例

A specific short-circuiting example in C

我明白了运算符短路的基本概念,但为什么

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

不予评价

因此,整个表达式的值等于分配给变量 m.

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

另一方面,正如开头所指出的那样,对表达式 i++ 求值。所以在这条语句之后 i 将等于 1.

int i = 0, j = -1, k = 1, m;

!(i++ && ++j) || ++k; ==> 只会计算 i++jk 不会计算

假设我们正在替换变量的值,那么表达式如下。

!(0 && ++ -1) || ++1

第一步: !(0 && ++ -1) ==> 对于 && 运算符,如果左侧操作数为 False,则我们不需要检查右侧操作数,因此 -1 不会递增,因此 j 的值将是 -1 本身。

因此 || 之前的左侧表达式变为 !(0)

第 2 步: !(0) || ++1

现在 !(0) 将为 1 ,因此对于 || 运算符,如果左侧操作数为 TRUE ,则​​无需去寻找右侧操作数,则 ++k 将不会执行.

m = 1 || ++1 ==> 1

因为只评估 i++ ,它会将其值更改为 1 所以输出是:1 -1 1 1