繁体   English   中英

使用条件

[英]The use of condition

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

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

它不是假的,当它为true时,您只打印false

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

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

if (1 <= 1)

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

if (2 <= 1)

这突出了问题所在,但甚至比那更糟。

您编写的代码具有未定义的行为,即“未定义”。 在这种情况下,编译器可以执行任何操作 ,但仍符合标准。


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

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

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

这是未指定行为的组合,只是简单的未定义行为 因此,您无法预测此代码的结果,因此无法依赖结果。 未指定,因为在此行中:

if(i<=i++)

我们不知道将首先评估i还是i++ C99标准草案6.5第3款规定

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

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

在上一个序列点与下一个序列点之间,对象的存储值最多只能通过对表达式的求值来修改 此外, 先验值应只读以确定要存储的值。

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

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

i++表示在比较之后i++递增。 在i的两个分支中,如果i正在递增,则等效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM