请解释&&的优先权之间明显的冲突。和||和表达式的实际结果

时间:2010-07-30 20:11:28

标签: c

我不明白以下程序的输出:

#include<stdio.h>

int main()
{
    int i=-3, j=2, k=0, m;
    m = ++i || ++j && ++k;
    printf("%d %d %d %d\n", i, j, k, m);
    return 0;
}

输出为-2 2 0 1而不是-2 3 1 1,这意味着在表达式之前评估了++i(并导致||运算符使其右侧短路) ++j && ++k似乎与&&运算符的优先级高于||的事实相矛盾。

有人会解释原因吗?

4 个答案:

答案 0 :(得分:22)

输出应该是这样的:

Error, line 2: 'm': undefined variable.

编辑:修复后,只应评估++i。优先权不会决定(甚至影响)评估顺序。优先级意味着表达式等同于++i || (++j && ++k)||&&的评估顺序始终是评估左操作数,然后是序列点。在序列点之后,当且仅在必要时评估右操作数以确定最终结果(即,如果左操作数被评估为零,则评估||的右操作数; {{1}的右操作数如果左操作数计算为非零,则计算}。

在这个表达式中,&&被计算,然后因为它是++i的左操作数并且被计算为非零,所以表达式的其余部分都不会被计算。

答案 1 :(得分:3)

-2 2 0 1

懒。

#include <stdio.h>

int main()
{

 int i=-3,j=2,k=0;
 int m=++i||++j&&++k;

 printf("%d %d %d %d",i,j,k,m);

}

编译,运行并亲眼看看。

gcc tmp.c -o tmp

答案 2 :(得分:2)

表达式:

++i || ++j && ++k

相当于:

(++i) || ((++j) && (++k))

解释

    评估
  1. ++i - (-2) || ((++j) && (++k));
  2. 评估||运算符 - (1);
  3. 由于1 || anything评估为真,因此不评估右操作数。因此,&&优先级在此无关紧要。 C和C ++中的相关标准保证了这种短路(见Is short-circuiting logical operators mandated? And evaluation order?)。

    现在,尝试使用子表达式,如下所示:

    (++i || ++j) && ++k
    

    相当于:

    ((++i) || (++j)) && (++k)
    

    解释

      评估
    1. ++i - ((-2) || (++j)) && (++k);
    2. 评估
    3. || - (1) && (++k)
    4. 评估
    5. ++k - (1) && (1);
    6. 评估为真;

答案 3 :(得分:0)

作为解释:

#include <stdio.h>

int main()
{
    if (-1)
        printf ("-1!\n");
    else
        printf ("Not -1.\n");
    return 0;
}

C中的负数不是假的。总是将布尔值与0(或FALSE)进行比较,否则可能会被if (worked == TRUE)误导为假阴性。