-1

先生,请您告诉我为什么' C '中的以下条件是false

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

4 回答 4

12

这不是假的,你只是false在它是真的时打印。

于 2013-08-30T01:49:48.690 回答
3

比较运算符<=没有指定首先评估哪一侧 thei/gnu-c-manual/gnu-c-manual.html#Sequence-Points)。i++

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

if (1 <= 1)

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

if (2 <= 1)

这突出了问题,但比这更糟糕。

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


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

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

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

于 2013-08-30T01:58:22.937 回答
1

这是未指定行为和简单明了的未定义行为的组合。所以你无法预测这段代码的结果,也不能依赖结果。未指定,因为在此行中:

if(i<=i++)

我们不知道是先评估i还是i++先评估。C99 标准部分草案第6.5 3 段说:

运算符和操作数的分组由语法指示。74) 除稍后指定(对于函数调用 ()、&&、||、?: 和逗号运算符)外,子表达式的求值顺序和中的顺序发生哪些副作用都未指定。

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

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

于 2013-08-31T03:36:27.837 回答
-3

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

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

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

于 2013-08-30T01:56:59.370 回答