猿问

i =(i,++ i,1)+1; 做?

阅读有关未定义行为和序列点的答案后,我编写了一个小程序:


#include <stdio.h>


int main(void) {

  int i = 5;

  i = (i, ++i, 1) + 1;

  printf("%d\n", i);

  return 0;

}

输出为2。哦,天哪,我没有看到减价的到来!这是怎么回事


另外,在编译上面的代码时,我得到警告说:


px.c:5:8:警告:逗号表达式的左操作数无效


  [-Wunused-value]   i = (i, ++i, 1) + 1;

                        ^

为什么?但是可能我的第一个问题的答案会自动回答。


ITMISS
浏览 755回答 3
3回答

隔江千里

在表达式中(i, ++i, 1),使用的逗号是逗号运算符逗号运算符(由标记表示,)是一个二进制运算符,它评估其第一个操作数并丢弃结果,然后评估第二个操作数并返回此值(和类型)。因为它丢弃其第一个操作数,所以通常仅在第一个操作数具有所需副作用的情况下才有用。如果未对第一个操作数产生副作用,则编译器可能会生成有关该表达式的警告,但无效。因此,在上面的表达式中,i将评估最左边的值并将其值丢弃。然后++i将被求值并将其递增i1,并再次++i舍弃表达式的值,但对to的副作用i是永久的。然后1将被求值,表达式的值将为1。相当于i;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Evaluate i and discard its value. This has no effect.++i;&nbsp; &nbsp; &nbsp; &nbsp; // Evaluate i and increment it by 1 and discard the value of expression ++ii = 1 + 1;&nbsp;&nbsp;请注意,上面的表达式是完全有效的,并且不会调用未定义的行为,因为在逗号运算符的左操作数和右操作数的求值之间存在一个序列点。

MM们

引自C11,章节6.5.17,逗号运算符逗号运算符的左操作数被评估为void表达式;在它的评估与正确操作数的评估之间存在一个顺序点。然后评估正确的操作数;结果具有其类型和价值。所以,就您而言,(i, ++i, 1)被评估为i,被评估为无效表达式,值被舍弃++i,被评估为无效表达式,值被舍弃最终1,值返回了。因此,最终声明看起来像i = 1 + 1;并i到达2。我想这可以回答您的两个问题,如何i获得值2?为什么会有警告消息?注意:FWIW,因为有一个序列中的点存在于左手操作数的评价后,表达等(i, ++i, 1)将不会调用UB,作为一个可普遍认为误。

慕桂英3389331

i = (i, ++i, 1) + 1;让我们逐步分析它。(i,&nbsp; &nbsp;// is evaluated but ignored, there are other expressions after comma++i,&nbsp; // i is updated but the resulting value is ignored too1)&nbsp; &nbsp; // this value is finally used+ 1&nbsp; &nbsp;// 1 is added to the previous value 1这样我们得到2。现在的最终赋值是:i = 2;无论是在我现在是覆盖前。
随时随地看视频慕课网APP
我要回答