For loop 在for循环中使用break是一种不好的做法吗?

For loop 在for循环中使用break是一种不好的做法吗?,for-loop,break,For Loop,Break,在for循环中使用break语句是一种不好的做法吗 比方说,我正在数组中搜索一个值。在for循环内部进行比较,找到值后,break退出for循环 这种做法不好吗?我已经看到了使用的替代方法:定义一个变量vFound,并在找到值时将其设置为true,然后在中检查vFound的语句条件。但是,是否有必要为此目的创建一个新变量 我在循环的正常C或C++的上下文中请求。< /P> 注意:建议不要使用break。在for循环中使用break以及continue,这是非常好的 它简化了代码并提高了可读性。这

for
循环中使用
break
语句是一种不好的做法吗

比方说,我正在数组中搜索一个值。在for循环内部进行比较,找到值后,
break
退出for循环

这种做法不好吗?我已经看到了使用的替代方法:定义一个变量
vFound
,并在找到值时将其设置为true,然后在
中检查
vFound
语句条件。但是,是否有必要为此目的创建一个新变量

我在循环的正常C或C++的上下文中请求。< /P>


注意:建议不要使用break。

for
循环中使用
break
以及
continue
,这是非常好的


它简化了代码并提高了可读性。

这取决于语言。虽然您可以在此处检查布尔变量:

for (int i = 0; i < 100 && stayInLoop; i++) { ... }
int[] iArray = new int[]{0,1,2,3,4,5,6,7,8,9};
int[] jArray = new int[]{0,1,2,3,4,5,6,7,8,9};

// label for i loop
iLoop: for (int i = 0; i < iArray.length; i++) {

    // label for j loop
    jLoop: for (int j = 0; j < jArray.length; j++) {

        if(iArray[i] < jArray[j]){
            // break i and j loops
            break iLoop;
        } else if (iArray[i] > jArray[j]){  
            // breaks only j loop
            break jLoop;
        } else {
            // unclear which loop is ending
            // (breaks only the j loop)
            break;
        }
    }
}

无论如何,
break
将使这两个代码更具可读性。

在您的示例中,您不知道for循环的迭代次数。为什么不改为使用while循环,它允许迭代次数在开始时是不确定的


因此,通常不必使用中断状态,因为循环可以更好地表示为循环。

否,中断是正确的解决方案


添加布尔变量会使代码更难阅读,并增加潜在的错误源。

您可以找到各种带有“break”语句的专业代码。在必要的时候使用它是完全有意义的。在您的情况下,此选项比仅为退出循环而创建单独的变量要好。

当然,
break
是停止for循环或foreach循环的解决方案。我在php的foreach和for循环中使用了它,发现它可以工作。

取决于您的用例。在某些应用程序中,for循环的运行时需要保持恒定(例如,为了满足某些时间限制,或者为了隐藏数据内部结构以防基于时间的攻击)

在这些情况下,甚至可以设置一个标志,并且只有在所有的
for
循环迭代实际运行之后才检查标志值。当然,所有for循环迭代都需要运行仍然需要大约相同时间的代码

如果您不关心运行时间。。。使用
break
继续使代码更易于阅读。

在我的公司C dev中使用的98条规则中,不能使用break语句


编辑:在MISRA'04中允许中断

中断是完全可以接受的语句(顺便说一句,继续也是如此)。这一切都是关于代码可读性的——只要你没有过度复杂的循环之类的东西,就可以了


这不像他们是同一个联赛的后藤

我同意其他人建议使用
break
。显而易见的问题是,为什么会有人提出相反的建议?好。。。使用break时,跳过块中的其余代码和其余迭代。有时这会导致错误,例如:

  • < P>在块的顶部获取的资源可以在底部释放(即使对于代码<块> <代码>循环)也是如此,但是当“过早”退出是由<代码> Buffe/Cuff>语句(在“现代”C++,“RAII”)引起时,可能会意外跳过该释放步骤。用于以可靠且异常安全的方式处理此问题:基本上,无论范围如何退出,对象析构函数都会可靠地释放资源)

  • 有人可能会更改
    for
    语句中的条件测试,而不会注意到存在其他非定域退出条件

  • ndim的回答指出,有些人可能会避免使用
    break
    s来维持相对一致的循环运行时,但您将
    break
    与使用布尔型早期退出控制变量进行了比较,而这并不成立

不时观察到这些错误的人会意识到,这种“不间断”规则可以预防/缓解这些错误。。。事实上,对于“更安全”的编程,有一个完整的相关策略,称为“结构化编程”,其中每个函数都应该有一个单独的入口和出口点(即,没有goto,没有提前返回)。它可能会消除一些bug,但无疑会引入其他bug。他们为什么这么做

  • 他们有一个开发框架,鼓励特定风格的编程/代码,他们有统计证据表明这在有限的框架中产生了净效益,或者
  • 在这样的框架内,他们受到编程指导原则或经验的影响,或者
  • 他们只是独裁的白痴,或者
  • 上述任何一种+历史惯性(相关的理由是,这些理由比现代C++更适用于C)

使用
break
是完全有效的-正如其他人所指出的,它与
goto
没有任何相同之处


尽管您可能希望在循环外部检查是否在数组中找到值时使用
vFound
变量。同样从可维护性的角度来看,使用一个通用标志来表示退出标准可能是有用的。

Python(和其他语言?)扩展了该结构,因此只有在循环不中断的情况下才会执行该结构的一部分

for n in range(5):
    for m in range(3):
        if m >= n:
            print('stop!')
            break
        print(m, end=' ')
    else:
        print('finished.')
输出:

stop!
0 stop!
0 1 stop!
0 1 2 finished.
0 1 2 finished.

不带
中断的等效代码
和方便的
其他

for n in range(5):
    aborted = False
    for m in range(3):
        if not aborted:
            if m >= n:
                print('stop!')
                aborted = True
            else:            
                print(m, end=' ')
    if not aborted:
        print('finished.')

在嵌入式世界中,有很多代码使用以下结构:

    while(1)
    { 
         if (RCIF)
           gx();
         if (command_received == command_we_are_waiting_on)
           break;
         else if ((num_attempts > MAX_ATTEMPTS) || (TickGet() - BaseTick > MAX_TIMEOUT))
           return ERROR;
         num_attempts++;
    }
    if (call_some_bool_returning_function())
      return TRUE;
    else
      return FALSE;
这是一个非常普通的例子,很多事情都发生在幕后,特别是中断。不要把它当作样板代码,我只是想举例说明
for (int x=0;x<fooCount;++x)
{
  Foo foo=getFooSomehow(x);
  if (foo.bar==42)
    break;
}
// So when we get here, did we find one, or did we fall out the bottom?
Foo findFoo(int wantBar)
{
  for (int x=0;x<fooCount;++x)
  {
    Foo foo=getFooSomehow(x);
    if (foo.bar==wantBar)
      return foo;
  }
  // Not found
  return null;
}
for(int i = 0; i < myCollection.Length && myCollection[i].SomeValue != "Break Condition"; i++)
{
//loop body
}
for(int i = 0; i < myCollection.Length && (i == 0 ? true : myCollection[i-1].SomeValue != "Break Condition"); i++)
{
//loop body
}
for(int i = 0; i < myCollection.Length && (i == 0 ? true : myCollection[i-1].SomeValue != "Break Condition"); i++)
{
    DoAllThatCrazyStuff(myCollection[i]);
}
for(int i = 0; i < myCollection.Length && BreakFunctionCheck(i, myCollection); i++)
{
    DoAllThatCrazyStuff(myCollection[i]);
}
int[] iArray = new int[]{0,1,2,3,4,5,6,7,8,9};
int[] jArray = new int[]{0,1,2,3,4,5,6,7,8,9};

// label for i loop
iLoop: for (int i = 0; i < iArray.length; i++) {

    // label for j loop
    jLoop: for (int j = 0; j < jArray.length; j++) {

        if(iArray[i] < jArray[j]){
            // break i and j loops
            break iLoop;
        } else if (iArray[i] > jArray[j]){  
            // breaks only j loop
            break jLoop;
        } else {
            // unclear which loop is ending
            // (breaks only the j loop)
            break;
        }
    }
}