【问题标题】:Increment and Decrement operators递增和递减运算符
【发布时间】:2011-02-16 12:22:07
【问题描述】:

下面的有效和无效是如何显示的,它们是什么意思。什么时候会出现这种情况来写这段代码。

++x = 5;     // legal
--x = 5;     // legal
x++ = 5;     // illegal
x-- = 5;     // illegal

【问题讨论】:

  • 家庭作业?考试题?
  • 两者都不是。只是想知道。
  • 虽然这段代码可以编译,但这不是一个好主意。目前还不清楚代码试图做什么,很容易分成两个简单、清晰的语句。这是一种“聪明”的编码,以后会困扰你。
  • @Kirill - 这不是重复的。 OP 在问为什么前两个编译而后两个不编译,而你的副本在问为什么前两个是未定义的行为。

标签: c++


【解决方案1】:

++x--x返回x(在增加/减少之后)。那时你可以用它做你想做的事,包括给它一个新的值。

x++x--返回x 的内容(只是它增加/减少之前)。改变这个值并不比改变任何普通函数的返回值更有意义:

obj->getValue() += 3; // pointless

【讨论】:

    【解决方案2】:

    我能想到的唯一可能发生这种情况的地方是 operator++ 和 operator= 的运算符重载。即使这样,定义也不清楚。你的代码基本上是在 x 上加一,然后给它赋值 5。会出现一个问题,例如为什么在分配 5 之前需要增加 x ?唯一可能的解释是,如果你有某种类,其中 ++ 运算符以某种方式增加一个内部计数器,然后是赋值。不知道为什么需要这样的东西。

    【讨论】:

      【解决方案3】:

      假设问题是关于内置的++-- 运算符,那么这些语句都不是严格合法的。

      前两个是格式良好的,即它们只是可编译,因为前缀递增的结果是左值。最后两个是格式错误的,因为后缀增量的结果不是右值,这就是你不能分配给它的原因。

      但是,从某种意义上说,即使是前两个也不合法,因为它们会产生未定义的行为。在没有中间序列点的情况下多次修改同一个对象是非法的。 (另请注意,允许编译器拒绝编译产生未定义行为的格式良好的代码,这意味着即使是第一对也可能被证明是不可编译的。

      【讨论】:

        【解决方案4】:

        鉴于 operator=() 和 operator++() 都可以重载,如果不了解更多关于运算符所应用的事物的类型,就不可能说出代码的作用。

        【讨论】:

        • 很好奇为什么这被否决了 - 这个人有一个有效的观点。我希望 OP 处理的是整数,但没有提到类型。
        • 我相信如果 x 是非标量类型,这甚至可能不会导致未定义的行为。
        • @DeadMG:当人们没有想到或认为它们太“花哨”或“迂腐”时,人们会否决。
        • 我没有投反对票,但可能是因为这更像是评论而不是答案。
        【解决方案5】:

        坦率地说,你永远不应该这样写。后增量和前增量(和减量)只能单独使用。它们只是混乱的秘诀。

        【讨论】:

        • 如果你只单独使用它们,那么后增量是一个毫无价值的操作符。
        • 我认为当 DeadMG 说“自己”时,他的意思是不要做双重分配。他不是有意排除if( x++ ) {/*...*/} 之类的东西。对吧,DeadMG?
        • 我绝对是有意排除这些。 Postincrement 和 pre-increment 是语法糖,在表达式中实际使用时并不好。如果你迫切需要这个,手动做,让编译器把它变成另一种形式。但我不知道在什么情况下你可能需要它。
        【解决方案6】:

        这些都在序列点之间多次修改x 的值,因此是未定义的行为,您应该小心避免。我看不出“合法”和“非法”之间的区别在哪里——因为行为是合法的,所以任何行为(包括向国务卿发送各种电子邮件)都完全符合标准。

        【讨论】:

          【解决方案7】:

          后缀 (x++/x--) 运算符不返回左值(可以赋值的值)。

          它们返回一个临时值,该值是更改前变量值的副本

          这个值是一个右值,所以你可以这样写:

          y = x++ 并获取 x 的旧值

          【讨论】:

          • @Bruno:为什么不呢?这就是后增量运算符的全部意义。
          猜你喜欢
          • 1970-01-01
          • 2015-10-03
          • 2014-03-21
          • 1970-01-01
          • 2010-12-01
          • 2015-02-16
          • 2011-08-29
          • 1970-01-01
          相关资源
          最近更新 更多