【问题标题】:Refactoring with the ternary operator in C在 C 中使用三元运算符进行重构
【发布时间】:2013-06-04 16:23:19
【问题描述】:

我创建了一个检查数组边界的函数。为什么我的第二个解决方案不执行与我的第一个解决方案相同的任务?这是优先级问题,还是三元组使用不当?

解决方法 #1:

bool check_bounds(double* score, int size)
{
    bool result=false;
    for(int i=0; i<size; i++)
    {
        if(score[i] < 0.0 || score[i] > 100.0) 
        {
            result=true;
        }
    }
    return result;
}

// usage
if(check_bounds(score, size) { i--; }

解决方法 #2:

bool check_bounds(double* score, int size)
{
    bool is_valid;
    for(int i=0; i<size; i++)
    {
        is_valid = (score[i] < 0.0 || score[i] > 100.0) ? true : false;
    }

    return is_valid;
}

【问题讨论】:

    标签: c refactoring ternary-operator


    【解决方案1】:

    你的第一个例子很早就脱离了:

    for(int i=0; i<size; i++)   // loop until i = size
    {
        if(score[i] < 0.0 || score[i] > 100.0) 
        {
            return true;   // but if we hit this condition, we leave now!
        }
    }
    

    您的第二个示例仅在 if 检查中设置变量:

    for(int i=0; i<size; i++) // loop until i = size regardless
    {
        is_valid = (score[i] < 0.0 || score[i] > 100.0) ? true : false;
    }
    
    return is_valid; // return whatever was last set.
    

    【讨论】:

    • 我明白你在说什么,迈克!我绝对不希望每次迭代都重新分配 is_valid 。谢谢你说清楚。
    【解决方案2】:

    您的第二个解决方法失败了,因为在 for 循环的每次迭代中,is_valid 都是基于 score[i] 分配的。这实质上会导致整个函数返回score[size - 1] &lt; 0 || score[size - 1] &gt; 100

    三元运算符在这里并不合适,因为它总是会被评估,并为is_valid 分配一个新值。第一个版本可以这样重写以展示它的实际作用:

    bool check_bounds(double*score, int size)
    {
        bool is_valid = false;
        for(int i=0; i<size; i++)
        {
            if (score[i] < 0.0 || score[i] > 100.0)
            {
                is_valid = true;
            }
        }
        return is_valid;
    }
    

    【讨论】:

      【解决方案3】:

      第二个版本遍历score[0]score[size - 1]的整个范围,然后返回测试的最后一个值,而第一个版本如果score数组的任何成员超出范围,则提前退出循环.您需要在第二个版本的 for 循环内的某处添加对 is_valid 的测试。

      由于您必须测试 is_valid 以确定是否提前返回,恕我直言,在这里使用三元运算符绝对没有任何好处(既没有提高可读性,也没有更简洁的代码)。

      第二个版本(当更正为提前返回时)可能会被编译器优化为与第一个版本几乎相同的机器代码,因此您在性能方面也没有任何收获。

      在风格方面,我更喜欢第一个版本,但这是个人喜好问题。有些人(和经理!)认为在任何给定的函数中都应该只有一个return 语句。如果您试图坚持该标准,那么这里有另一种可能的重构:

      bool check_bounds(double* score, int size)
      {
          bool is_valid;
          for (int i=0; i<size; i++)
          {
              is_valid = (score[i] < 0.0 || score[i] > 100.0) ? true : false;
              if (!is_valid)
                  break;
          }
      
          return is_valid;
      }
      

      【讨论】:

      • 你说得对,我通常只使用三元运算符作为漂亮干净的返回语句。我想看看是否还有其他选择。我会坚持使用第一个版本并修复它。感谢您的反馈!
      【解决方案4】:

      解决方法 #1 如果在任何迭代中都满足条件,则返回 true,如果从未满足,则返回 false。解决方法 #2 在每次迭代中反复在真假之间切换,并返回最后一次迭代是否满足条件,这绝对不是您想要的。要获得 #1 的功能,您不能真正使用三元条件。

      【讨论】:

        猜你喜欢
        • 2019-04-28
        • 2020-11-23
        • 2023-03-05
        • 2013-11-20
        • 1970-01-01
        • 2010-12-13
        • 2016-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多