c - 关系运算符会影响赋值运算符操作吗?

标签 c

为什么下面提到的程序的输出是 0 而不是 20

#include <stdio.h>

int main()
{
    int i = 10, j = 0;
    if (i || (j = i + 10))
       /* do something */;                
    printf("%d\n",j);
}

最佳答案

是的,这个概念叫做Short-Circuit (在逻辑&&|| 运算符表达式中)。

对于任何逻辑表达式(包括||&&),编译器会在计算结果后立即停止计算表达式(并保存执行)。

短路的技巧是:

!0 || any_expression == 1,所以any_expression不需要求值。

因为在你的表达式中 i 不是零而是 10,所以你可以认为条件 (i || (j = i + 10)) 就像

Logical OR operator:
The || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.

对于 &&(和运算符)类似:
0 && any_expression == 0,所以any_expression不需要求值。

在你的表达中:

(i || (j = i + 10) )
      ------------
       ^
       | Could evaluate if i is 0, 
       as i = 10 (!0 = true), so j remains unchanged as second operand is not evaluated

For 或 || 运算符的答案可以是 0 或 1。为了节省执行时间,一旦找到结果,评估就会停止。因此,如果第一个操作数为非零,则表达式的结果将为 1(如上)。因此,对于第一个操作数 i = 10 比较不等于 0,第二个操作数 (j = i + 10) 未被评估,因此 j 保持 0 因此您的代码输出为 0

注意:短路行为不仅存在于 C 语言中,而且概念在许多语言(如 Java、C++、Python)中都很常见。 (但不是全部,例如 VB6)。

在 C 语言中,保证逻辑表达式的短路一直是 C 语言的一个特性。Dennis Ritchie 设计和实现第一个 C 版本时就是如此,在 1989 年的 C 标准中仍然如此,在 C99 中仍然如此标准。

相关帖子:Is short-circuiting boolean operators mandated in C/C++? And evaluation order?

关于c - 关系运算符会影响赋值运算符操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17740980/

相关文章:

c++ - 优化 SphereInFrustrum 检查

c++ - 将 do-while 循环压缩为 #define 宏

c - 如何更新结构体中的字段?

C - 指针算术

c - fscanf - C 中的段错误(核心转储)

c - 在 C 中调试段错误

c - 结构类型数组。在结构内部有指针

php - 截断的 mt_rand() 更安全吗?

c - 链接列表不会删除列表中的第二 (2) 条记录,但适用于所有其他记录

c - 重定向标准输出,不理解行为