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