在C语言中的逻辑运算符 | |

3

我很难理解下面代码的行为:

#include <stdio.h>

int main(void)
{
    int i;
    int j;
    int k;

    i = 7;
    j = 8;
    k = 9;
    printf("%d\n", (i = j) || (j = k));
    printf("%d, %d, %d\n", i, j, k);

    return (0);
}

输出:

1
8, 8, 9

问题:

  • 我理解 expr1 | | expr2 的值为 1 如果 expr1 或者 expr2(或者两个都有)的值为非零.

  • i 的值从 7 增加到 8 是因为 i 被赋值为 j 的值。但是同样的方式,为什么 j 的值没有增加即使 j=k呢?我预期应该有一个

输出

1
8, 9, 9

8
|| 是一个短路运算符,意思是如果右半部分不必要,它就不会对其进行评估,就像在这个例子中一样。 - mousetail
1
(i = j) 表示你正在将 j 的值赋给 i。你是想要赋值还是比较?如果是比较,请使用 == 运算符。 - kiner_shah
1
我建议阅读运算符优先级。 - Sorenp
1
@Sorenp,“运算符优先级”在这里不相关,按照编写的代码只有一种解析方式。问题出在短路求值上。 - M.M
1
短路行为虽然通常不被认为是良好的风格,但可以用于错误处理,例如 fread(b, 1, 500, fp) == 500 || printf("Read failed"); - M.M
显示剩余2条评论
2个回答

5

从C标准(重点在于):

与按位 | 运算符不同, || 运算符保证从左到右进行求值;如果评估第二个操作数,则在评估第一和第二个操作数之间有一个序列点。如果第一个操作数与0不相等,则不会评估第二个操作数。

上述行为通常被称为运算符短路。

在您的示例中,由于(i = j)不为零,因此不会评估第二个操作数。


3

首先,

true || truetrue

true || falsetrue

false || truetrue

false || falsefalse

因此运算符||计算第一个表达式,如果它为true,则不会检查第二个表达式。

在你的特定情况中,(i = j)等于8,被认为是真的,因为只有int值等于0时才被认为是false。 因此,第二个(j = k)永远不会被计算,这就导致了你的结果。


非常感谢您,Bomber Cubit。我现在明白了! - Ajo Mathew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接