2013-06-04 20 views
0

我做了一个检查数组边界的函数。为什么我的第二个解决方案与我的第一个解决方案不一样?这是一个优先问题,还是三元组的不正确使用?用C中的三元运算符进行重构

变通方法#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; 
} 

回答

3

你的第一个例子破坏得早:

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! 
    } 
} 

你的第二个示例仅设置变量中,如果检查:

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. 
+0

我明确地看到你在说什么迈克!我绝对不希望在每次迭代中重新分配is_valid。感谢您的澄清。 – theGrayFox

3

你的第二个解决方法是失败,因为在for循环的每次迭代中,is_valid基于score[i]分配。这基本上导致整个函数返回score[size - 1] < 0 || score[size - 1] > 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; 
} 
0

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

2

第二个版本贯穿的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; 
} 
+0

你说得对,我通常只使用三元运算符作为干净的return语句。我想看看是否有其他的选择。我会坚持第一个版本并修复它。我很欣赏反馈! – theGrayFox