为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

ITMISS 2019-11-27 14:04:35
阅读有关未定义行为和序列点的答案后,我编写了一个小程序:#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;                        ^为什么?但是可能我的第一个问题的答案会自动回答。
查看完整描述

3 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

在表达式中(i, ++i, 1),使用的逗号是逗号运算符


逗号运算符(由标记表示,)是一个二进制运算符,它评估其第一个操作数并丢弃结果,然后评估第二个操作数并返回此值(和类型)。


因为它丢弃其第一个操作数,所以通常仅在第一个操作数具有所需副作用的情况下才有用。如果未对第一个操作数产生副作用,则编译器可能会生成有关该表达式的警告,但无效。


因此,在上面的表达式中,i将评估最左边的值并将其值丢弃。然后++i将被求值并将其递增i1,并再次++i舍弃表达式的值,但对to的副作用i是永久的。然后1将被求值,表达式的值将为1。


相当于


i;          // Evaluate i and discard its value. This has no effect.

++i;        // Evaluate i and increment it by 1 and discard the value of expression ++i

i = 1 + 1;  

请注意,上面的表达式是完全有效的,并且不会调用未定义的行为,因为在逗号运算符的左操作数和右操作数的求值之间存在一个序列点。


查看完整回答
反对 回复 2019-11-27
?
MM们

TA贡献1886条经验 获得超2个赞

引自C11,章节6.5.17,逗号运算符


逗号运算符的左操作数被评估为void表达式;在它的评估与正确操作数的评估之间存在一个顺序点。然后评估正确的操作数;结果具有其类型和价值。


所以,就您而言,


(i, ++i, 1)

被评估为


i,被评估为无效表达式,值被舍弃

++i,被评估为无效表达式,值被舍弃

最终1,值返回了。

因此,最终声明看起来像


i = 1 + 1;

并i到达2。我想这可以回答您的两个问题,


如何i获得值2?

为什么会有警告消息?

注意:FWIW,因为有一个序列中的点存在于左手操作数的评价后,表达等(i, ++i, 1)将不会调用UB,作为一个可普遍认为误。


查看完整回答
反对 回复 2019-11-27
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

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

让我们逐步分析它。


(i,   // is evaluated but ignored, there are other expressions after comma

++i,  // i is updated but the resulting value is ignored too

1)    // this value is finally used

+ 1   // 1 is added to the previous value 1

这样我们得到2。现在的最终赋值是:


i = 2;

无论是在我现在是覆盖前。


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 723 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信