【问题标题】:Conditional operator in CC中的条件运算符
【发布时间】:2023-04-03 12:44:01
【问题描述】:

是否可以将每个 if...then...else 语句转换为仅使用的等效语句?:

【问题讨论】:

    标签: c ternary-operator


    【解决方案1】:

    虽然我能想到的三元运算符的任何用途都可以实现为 if/else,但反之则不成立;至少在不使用在性能、可读性或可维护性方面没有任何好处的不正当和毫无意义的“技巧”的情况下是这样。

    if/else 的语法是:

    if( <boolean expression> )
        <statment>|<statment block>
    else
        <statment>|<statment block>
    

    而 ?: 三元运算符的语法是:

    <boolean expression> ? <expression> : <expression> ;
    

    这里重要的是&lt;expression&gt;&lt;statement&gt; 是不同的句法元素。

    表单的使用非常有限:

    if( b ) x = y else x = z ;
    

    可以实现为:

    x = b ? y : x ;
    

    但这里的限制是在 true 和 false 子句中都分配了相同的变量(因此 y 和 z 至少都可以转换为 x 的类型)。所以可以说,任何条件赋值都可以用三元运算符来实现(毕竟这是它的主要目的)。

    既然函数调用是一个有效的表达式,你可以将真假子句包装在单独的函数中,但这样做只是为了证明一个观点有点不正当:

    if( b )
        true_stuff() ;
    else
        false_stuff() ;
    

    相当于:

    b ? true_stuff() : false_stuff() ;
    

    这些函数可以包含任何代码。

    因此,要将更一般的 if/else 情况转换为 ?: 操作,必须首先将 true/false 语句块包装在单独的函数中。然而即便如此,Neil Butterworth 的示例仍将击败这种方法,因为 breakcontinuereturn 的行为会影响超出 if/else 构造范围的控制流(尽管这些可能也是您想要的代码示例避免!)。在 if/else 中出现goto 也会破坏这种方法。 .

    我想最后,即使你可以,你为什么要这样做?

    【讨论】:

      【解决方案2】:

      没有。

      条件表达式的两个“分支”必须计算为相同的类型,并且该类型不能是void

      例如,您可以这样做:

      x > 0 ? printf("Positive!\n") : 0;
      

      因为printf 返回int。 (不过,我只会在一轮代码高尔夫中使用它;事实上,I just did。)

      但你不能这样做:

      x > 0 ? exit() : 0;
      

      因为exit 返回void(或者,实际上,根本不返回)。

      【讨论】:

      • 你不能写一个函数返回int,然后调用exit(0),然后返回0吗?然后做x &gt; 0 ? myExit() : 0;。这会起作用,所以我认为答案实际上是“是的,如果你没有更好的事情可做”。
      • 你可以,但这毫无意义。此外,如果 if/else 语句包含大量代码,而不仅仅是一个或两个语句,这也不起作用。
      • 只有当您尝试分配 ?: 的结果或将其用作参数时,您关于 type 和 void 的第一点才是正确的。您的第二个示例至少在 MSVC++2008 中编译和运行。
      • @Clifford:嗯,你说得对。有趣的。在这种情况下,0 是否会转换为 void
      • 它似乎被视为简单的空语句。例如int main(){ 0;} 编译但不为 0 生成代码;语句(或实际上任何其他未分配的常量表达式)。
      【解决方案3】:

      代码:

      if ( flag ) {
         exit(1);
      }
      else {
         return 0;
      }
      

      无法转换成:

      flag ? exit(1) : return 0;
      

      一个更好的例子 - 这将在一个循环内:

      if ( flag ) {
         continue;
      }
      else {
         break;
      }
      

      无法转换为:

      flag ? continue : break;
      

      【讨论】:

      • 你可以做return (flag ? exit(1),1 : 0),但这太丑了。
      • @Pavel Radzivilovsky 看看这里:codepad.org/YU33Orwj 只有当我们将 void 分配给某个变量时它才会起作用,除非它完美地工作。
      • 我想我想出了一个方法,答案是肯定的;然后看了你的例子!最后,我的建议是适当地而不是反常地使用这些结构——这会使问题变得无关紧要。
      猜你喜欢
      • 2015-07-12
      • 1970-01-01
      • 2011-03-21
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 2014-08-09
      • 2011-02-21
      相关资源
      最近更新 更多