【问题标题】:Assignment in ternary operator三元运算符中的赋值
【发布时间】:2021-04-29 16:20:30
【问题描述】:

对于三元运算符,为什么会编译:

a > b ? a=4 : ' ';

但是这个没有:

a > b ? ' ' : b=4;

需要左值作为赋值的左操作数

也就是说,true case 与 false case 的赋值有何不同?

【问题讨论】:

    标签: c conditional-operator


    【解决方案1】:

    :? 的运算符优先级高于赋值运算符。所以后者相当于:

    (a > b ? ' ' : b)=4;
    

    这显然是非法的。

    【讨论】:

    • 我明白了,所以我只需要括号来执行第二种情况而不会出现编译器错误。
    • 并且代码可以使用括号来实现所需的结果:a > b ? (a = 4) : ' ';a > b ? ' ' : (b = 4);(这是对称的,即使在第一种情况下不是绝对必要的)。括号避免了编译器和人类代码阅读器产生歧义的所有风险。只做一个分配似乎有点可疑(为什么将 control-D 分配给这个表达式所分配的任何东西),但如果没有比显示更多的代码,很难知道。如果没有分配或以其他方式使用表达式,那么使用三元运算符是完全不合适的——使用if 语句。
    【解决方案2】:

    这与条件运算符的正式定义有关。来自C standard 的第 6.5.15 节:

    conditional-expression:
      logical-OR-expression
      logical-OR-expression ? expression : conditional-expression
    

    条件的第二个子句可以是任何表达式,而第三个子句只能是一个条件表达式(其中 as assignment 不是)。换句话说,条件运算符?: 的优先级高于赋值运算符=

    所以这个:

    a > b ? a=4 : ' '
    

    和这个是一样的:

    (a > b) ? (a=4) : (' ')
    

    但是这个:

    a > b ? ' ' : b=4;
    

    和这个一样:

    ((a > b) ? (' ') : b)=4;
    

    并且条件运算符的结果不能被赋值(即它不是左值)所以你会得到一个错误。

    如果你添加括号,你可以得到编译的东西:

    a > b ? ' ' : (b=4);
    

    当然,这些语句看起来不是条件的最佳用例,可能应该重写为:

    if (a>b) a=4;
    

    还有:

    if (a<=b) b=4;
    

    【讨论】:

      【解决方案3】:

      这是你应该知道的 C 和 C++ 之间存在本质区别的情况。:)

      在 C 中,条件(三元)运算符的定义如下

      conditional-expression:
          logical-OR-expression
          logical-OR-expression ? expression : conditional-expression
      

      像 C++ 一样

      conditional-expression:
          logical-or-expression
          logical-or-expression ? expression : assignment-expression
      

      所以在 C 中这个语句

      a > b ? ' ' : b=4;
      

      等价于

      ( a > b ? ' ' : b ) = 4;
      

      因此编译器会发出错误,因为您可能没有将值分配给其他值。

      来自 C 标准(6.5.15 条件运算符)

      4 计算第一个操作数;之间有一个序列点 它的评估和第二个或第三个操作数的评估 (以评估为准)。只有当 首先比较不等于0;仅在以下情况下评估第三个操作数 第一个比较等于 0; 结果是第二个的值 或第三个操作数(以被评估者为准),转换为类型 如下所述

      在 C++ 中,此语句等价于

      a > b ? ' ' : ( b=4 );
      

      并且是一个有效的陈述。

      这是一个演示程序

      #include <iostream>
      
      int main() 
      {
          int a = 0, b = 1;
          
          a > b ? ' ' : b=4;
          
          std::cout << "b = " << b << '\n';
          
          return 0;
      }
      

      它的输出是

      b = 4
      

      【讨论】:

        猜你喜欢
        • 2013-06-28
        • 2021-11-23
        • 2011-07-02
        • 2012-02-14
        • 1970-01-01
        • 2017-07-16
        • 2015-04-06
        • 1970-01-01
        • 2014-02-12
        相关资源
        最近更新 更多