使用条件

时间:2013-08-30 01:47:27

标签: c

先生,您能否告诉我为什么“ C ”中的以下条件为false

main()
{
    int i=1;
    if(i<=i++)
        printf("false");
    else
        printf("true");
}

4 个答案:

答案 0 :(得分:12)

这不是假的,你只需打印false就可以了。

答案 1 :(得分:2)

比较运算符<=未指定首先评估哪一方,ii++,并且左侧末尾没有序列点操作数到比较函数(见http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Sequence-Points)。

如果首先评估左侧,则得到:

if (1 <= 1)

如果首先评估右侧,则得到:

if (2 <= 1)

这凸显了这个问题,但情况甚至更糟。

您编写了具有未定义行为的代码,这意味着“未定义”。在这种情况下,编译器可以执行 anything ,并且仍然符合标准。


例如,这些编译器(-O3)遵循else分支:

虽然这些编译器(-O3)遵循true分支:

其他编译器可以做一些完全不同的事情。

答案 2 :(得分:1)

这是一个组合unspecified behavior,简单明了undefined behavior。因此,您无法预测此代码的结果,并且无法依赖结果。它没有说明,因为在这一行:

if(i<=i++)

我们不知道是先评估i还是i++draft C99 standard部分6.5 第3段表示:

  

运算符和操作数的分组由语法表示.74)除了稍后指定的(对于函数调用(),&amp;&amp;,||,?:和逗号运算符),子表达式的评估顺序和副作用发生的顺序都是未指定的。

上面提到的行也是未定义的行为,因为在sequence points之间我们只允许修改一次变量,如果我们修改它,我们只允许读取前一个值来确定要设置的新值。在这种情况下,我们正在阅读先前值,以确定ii++。从草案标准部分6.5 第2段

  

在上一个和下一个序列点之间,对象的存储值最多只能通过表达式的计算修改一次。此外,先前的值应该是只读的,以确定要存储的值。

答案 3 :(得分:-3)

要了解你的代码在做什么,我将重写,只会非常明确:

main()
{
    int i=1;
    if(i<=i) {
        i++;
        printf("false");
    } else {
        i++:
        printf("true");
    }
}

i++表示在比较后增加i 。在if i的两个分支中都是递增的,所以它是等价的。