棘手的表达评估

时间:2014-11-30 16:53:03

标签: c

我有这段代码:

  int main()
    {
       int a=1,b=2,c=3;
       printf("%d\n",a+=(a+=3,5,a));


       return 0;
    }

导致打印8。这怎么可能?

在第1步中,取出a+=3后a = a + 3使其成为a=4

在第2步中,a+=(a+=3)我将其设为a=a+(4),因此a=4+4=8。以这种方式移动我没有成功使a+=(a+=3,5,a)等于8。

2 个答案:

答案 0 :(得分:3)

逗号运算符既是序列点,也定义了评估顺序(如C规范的6.5.17节)。此运算符计算左操作数,然后计算右操作数并生成右操作数的值。

让我们打破这个:

(a+=3,5,a)

这将在a中加3,然后产生右手的值,即:

5, a

它将5评估为5,然后将其丢弃。然后它将评估a,然后产生值a(即4)。其余的则变为:

a+=4

其中a添加4,然后产生a的新值,即8。

注意:这可能是未定义的行为,请参阅下面的Vlad的答案。

答案 1 :(得分:2)

该程序具有未定义的行为,因为。根据C标准(6.5.16分配运营商)

  
      
  1. ...更新左操作数存储值的副作用在左右值计算后排序   操作数。对操作数的评估未经过排序
  2.   

所以在你的例子中,可能首先评估左操作数,它将等于tp 1。 在这种情况下,您将得到等于5的结果。

在复合赋值的右侧,没有任何意义在逗号运算符中包含操作数5和a。你可以写简单

a += ( a += 3 );

而不是

a+=(a+=3,5,a));

或者你可以让代码更有趣。例如

a+=(a+=3, 1, 2, 3, 4, 5,b, c, a));