【问题标题】:Ternary Operator Not Generating Error三元运算符不产生错误
【发布时间】:2015-07-21 02:20:45
【问题描述】:

我熟悉三元运算符已经有一段时间了,并且使用过几种不同的语言。我对运营商的理解是这样的:

condition ? expr1 : expr2 但是,在 C++ 中,以下代码是合法的:

int i = 45;
(i > 0) ? i-- : 1;

实际上,您不只是写1;i - 1;这是一个完整的声明吗?我知道代码的目的是减少 i 如果它大于 0,但我认为代码会产生编译器错误,因为它只是一个表达式,而不是一个完整的语句。我期望这样的代码:

int i = 45;
i = (i > 0) ? i - 1 : i;

【问题讨论】:

标签: c++ ternary-operator


【解决方案1】:

这称为表达式语句。对表达式求值并丢弃其值。

即使这是有效的:

42;

虽然它什么也没做。只有表达式中的副作用(如i--、赋值等)才有效果。


其实我们使用的很多语句都是表达式语句:赋值、函数调用等:

a = 42;
foo();

【讨论】:

  • 谢谢;不知道 42; 是合法的 C++ 代码。我想我只是习惯了 Java 以及它如何处理表达式和语句。
【解决方案2】:

这是一个有效的表达式。您可能会收到警告,因为您没有保存表达式的结果,但您有 i-- 您的语句确实有效。

【讨论】:

    【解决方案3】:

    在 C++ 中,像 1 这样的表达式是完全有效的语句,没有副作用。您可以非常可行地编写此函数:

    void f() {
        1;
    }
    

    事实上,即使这样也是正确的。

    void f() {
        ;;;;
    }
    

    文字语句评估它的参数,但什么也不做。系统将1; 视为就像func();。唯一的区别是,虽然func(); 在逻辑上会产生一些副作用,但1; 没有,所以它最终成为无操作。三元运算符的计算类似于 if 语句,因此仅当操作数为真时才计算第二种形式。因此:

    (i > 0) ? i-- : 1;
    

    如果 i 大于 0,则计算第二种形式。当它被求值时,它带有它的副作用,即 i 减 1。否则,第三种形式被求值,它什么也不做。尽管这段代码有效,但它的可读性并不高,所以虽然它是很好的玩具代码,但真正的 if 语句非常适合这种情况。出于同样的原因,这行代码会产生同样的效果,但同样难以理解。

    ((i > 0) && (i--)) || 1;
    

    假设您没有覆盖布尔运算符,此代码将短路并表现得像三元运算符。如果 i 不大于 0,则 && 不需要计算其第二个操作数,因为 && 为假,但 ||必须,因为它可能是真的。相反,如果 i 大于 0,则 && 需要计算,但 ||已经知道这是真的。

    【讨论】:

      【解决方案4】:

      实际上,你不只是写 1 吗?或 i - 1;

      否:i--i - 1 不同。在第一种情况下,i 的值被修改。第二种情况则不然。

      如果i 小于或等于零,那么您正确的结果是“代码”将为1。然而,编译器会意识到这不是一个有用的东西,所以它应该生成相当于:

      if( i > 0 ) i--;
      

      有些人(包括我自己)会认为以这种方式使用三元运算符是不好的风格。只是为了好玩,这里有另一种可能有人写它的方式也不是很好(也更有可能产生编译器警告):

      i > 0 && i--;
      

      最后,风格是一个偏好问题。在大多数情况下,编译器将决定将代码转换为汇编的最佳方式。所以你应该为自己编写清晰简洁的代码。

      【讨论】:

        猜你喜欢
        • 2018-09-07
        • 2018-04-11
        • 2014-05-03
        • 2017-05-12
        • 2012-11-19
        • 1970-01-01
        • 2013-04-21
        • 2017-09-05
        • 2013-06-24
        相关资源
        最近更新 更多