3

代码:

#include<stdio.h>
int main()
{
    int j = 7, i = 4;
    j = j || ++i && printf("you can");
    printf("%d %d",i,j);
    return 0;
}

输出:4 1

[代码链接][1]

  1. 前缀运算符的优先级高于逻辑运算符。2.Logical&&的优先级高于logical ||
  2. 在逻辑与(&&)中,如果第一个操作数的计算结果为假,则不会计算第二个,而在逻辑或(||)如果第一个操作数的计算结果为true,则不会计算第二个。
  3. 完整的表达式计算结果为true,因此 j 为 1 。

疑点:

  1. 为什么这里不遵循第一条规则?不应该是正确的吗?

    j=(j||((++i) &&printf("you can")));
    

i因此,在printf语句中的值变为 5。

为什么这里违反了一般优先规则?当两个运算符的优先级相同时,关联性就会起作用。编译器不应该先看看是评估||还是&&

如果||首先评估,这不应该据我所知,那么结果是正确的。但是,如果它没有先被评估,那么你应该打印 can51。

4

4 回答 4

4

在这个表达式中:

j = j || ++i && printf("you can");

之后有一个序列点||,它从左到右进行评估。由于 j 不为零,因此不计算表达式的其余部分。因此,j || (....)变为真,即 1。由于++i未评估 i,因此 i 保持为 4。因此,输出为4, 1

来自 C 标准:

附件 C

— 以下运算符的第一个操作数的结尾:逻辑 AND && (6.5.13);逻辑或 || (6.5.14);有条件的?(6.5.15);逗号 , (6.5.17)。

如果你j是零,那么++i && printf("you can")将被评估并i成为 5 并且you can也将被打印。您对 ++ 的优先级大于 || 是正确的,但由于存在序列点,j||因此首先进行评估。

于 2012-09-24T16:47:40.683 回答
3

j || ++i && printf("you can")计算结果为真,由 表示1。因为它是一个 OR,并且因为 j 不为零,所以只计算 OR 的左手,所以不计算the++i和 the 。printf因此j为 1 并i保持为 4。

当然,真正的代码不应该每个人都做这样的事情。您应该始终以操作顺序显而易见的方式编写代码,并且您几乎不应该在 OR 语句中使用带有副作用的代码。

于 2012-09-24T16:38:13.820 回答
2

你在这里有什么:

j = j || ++i && printf("you can");

是一个逻辑表达式(没有数学发生)。让我们分解一下:

++i                // as a mathematical expression this is i=i+1 (5 in your case)
printf("you can"); // printf returns the number of chars written, (7)

所以你会期望这是:

j = 7 || 5 && 7;

上面表达式的输出只是 1。所以即使执行了这个,你也应该看到j=1. 那么为什么看不到printf()输出呢?原因是整个表达式没有运行。它不必。考虑:

result = TRUE || (anything else);

任何“真实”的东西或与其他任何东西一起使用的东西都会返回真实的。编译器知道这一点,一旦它看到7 ||它等同于true ||并说“我知道的足够多,将 j 设置为 true 并继续前进”。

这就是表达式不增加 i 以及不打印“you can”的原因。现在,如果您要翻转表达式:

j = ++i && printf("you can") || j; 

逻辑保持不变,但编译器看不到 || 直到它评估了其他所有内容,所以 i 将被递增并且 printf 将被显示。

于 2012-09-24T17:08:48.783 回答
1

我以两种方式运行该程序:

j = j || ++i && printf("you can");

然后,像这样:

j = j || (++i && printf("you can"));

两者的输出都是4 1. 在我运行它们之前,由于逻辑或的从左到右的关联性,我希望从两者中得到完全相同的结果。无论如何,整个表达式将从左到右进行评估。括号的作用是确保一个表达式作为一个表达式被计算,并不一定意味着它将是第一个被计算的表达式。如果您想要更多证据,请尝试一些简单的方法:

j = 1 || (++i);

即使(++i)在括号中,它也不会被评估。同样,因为从左到右的关联性。

于 2012-09-24T17:29:32.967 回答