【问题标题】:Why This Code Prints Second statment?为什么此代码打印第二条语句?
【发布时间】:2025-12-25 23:20:18
【问题描述】:

为什么此代码在第一个 If 语句中失败?

根据关联和优先级,我的预测出错了。

 #include<stdio.h>

    void main()
    {
            int i=10;
            if(i==i--)
            {
                printf("In 1:%d\n",i);
                printf("TRUE 1\n");
            }   
            i=10;
            if(i==--i)
            {
                printf("In 2:%d\n",i);
                printf("TRUE 2\n");
            }
    }               

【问题讨论】:

  • 表达式i == i--i == --i 中没有排序,因此您有未定义的行为
  • 你能给我解释一下吗?@JoachimPileborg
  • 有关技术位,请阅读evaluation order and sequencing
  • 这是一个帮助.. @JoachimPileborg

标签: c


【解决方案1】:

表达式i==i-- 将导致未定义的行为,因为ii-- 的两次计算之间没有序列点。这意味着任何事情都可能发生,此时程序不再产生有意义的输出。

表达式i==--i也是如此

如果读取并修改了一个对象,但没有分隔两个事件的序列点,则行为未定义1。在这种情况下,相同的对象被修改(副作用):i-- 并读取(值计算):i,没有序列点。

正确的代码会用序列点(字符;)分隔两个表达式:

const int i1 = i;
const int i2 = i--;
if( i1 == i2 )
{
    //...
}


const int i3 = i;
const int i4 = --i;
if( i3 == i4 )
{
    //...
}

1(引自 ISO/IEC 9899:201x 6.5 表达式 2):
如果标量对象上的副作用相对于不同的副作用是未排序的 在同一标量对象或使用同一标量的值的值计算上 对象,行为未定义。

【讨论】:

    【解决方案2】:

    不会有编译错误。它不会进入第一个 if 语句,因为它是未定义的行为(正如用户 babon 所提到的)。

    行为实际上取决于您使用的编译器。

    【讨论】:

      【解决方案3】:

      未定义的行为,因为 postpre 的增量取决于编译器。请看堆栈溢出问题here.

      C99 标准 - 6.5 表达式,§2

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

      【讨论】:

        【解决方案4】:

        我不太明白你的问题。您是在问“为什么只有在执行时才首先执行语句”?如果是,原因如下

        i-- 计算表达式然后递减 --i 先递减,然后计算表达式。因此,第二个条件的计算结果为“假”(10 == 9)

        【讨论】:

        • 第二个 if 语句呢? @Bhaktvatsal
        • @M.SCaudhari no ;在没有定义顺序的情况下发生递减和评估。这就是行为未定义的原因。
        【解决方案5】:

        i==i-- 是未定义的行为。请检查这个:http://c-faq.com/expr/ieqiplusplus.html 和这个:http://c-faq.com/expr/seqpoints.html

        【讨论】: