当我还是一年级新生时,我们的导师允许我们在循环中使用 break
或 continue
。那时候我大多数情况下都这样做,因为它可以终止/继续循环。现在我已经是大二学生了,我的导师告诉我不建议使用 break
/continue
。你能告诉我原因吗?顺便问一下,break
/continue
会造成什么影响呢?
有些人认为,控制流太复杂是不好的,这意味着像break
,continue
和多个return
之类的东西。原因不是技术上的,而是复杂的控制流可能会使程序更难以验证、测试和推理。
然而,这在很大程度上取决于个人风格、个人口味和整体结构。对于小型、目的明确的函数,可能没有什么问题可以有多个可能的流程。特别是在C++中,早期退出是一种常用的习惯,通常可以使代码更易于跟踪。
return
语句,C++程序也可能具有非常复杂的控制流:在此之后可能会运行许多析构函数,更不用说异常了。但是,像所有东西一样,要适度使用。 - ta.speot.isbreak
或continue
(更不用说return
了)。正如Kerrek所说,这会使得对代码正确性的推理变得更加困难。 - James Kanzeif
语句和对result
变量的赋值比仅使用return
更加混乱。 - Bolpatfor (;;) {
// ...
if ( conditionMet ) {
break;
}
// ...
}
对于经典的循环半个习语来说,这是可以接受的;毕竟,它是单入口/单出口的,即使出口不在我们期望的位置上(并且在阅读代码时很难找到)。但关于循环不变量的问题仍然存在;它们在if
之前没有满足,至少在第一次执行时如此。通常,更好的解决方案是将测试代码放入一个单独的函数中,该函数返回conditionMet
,并使用:
while ( doLoopPrefix() ) {
doLoopSuffix();
}
switch
语句,并且拥有很多情况。break
和/或continue
来控制循环的流程。你的循环条件应该表明在什么情况下循环应该停止;维护你的代码的人不应该必须深入到循环体中的代码中去查看触发break
导致循环停止的原因是什么。inputFile
的文件中读取若干个整数并检查其中是���有一个整数是500。一种规范循环结构的方式如下:while (fgets (buffer, sizeof (buffer), inputFile)){
sscanf (buffer, "%d", &num);
if (num == 500)
break;
}
在这里,阅读代码的人必须读完整个while
循环才能弄清楚您实际上要在文件中查找什么。如果您没有使用break
编写此代码:
while ((num != 500) && fgets (buffer, sizeof (buffer), inputFile))
sscanf (buffer, "%d", &num);
break
)来换取另一个复杂的循环条件。对我来说,第一个版本更清晰明了,我认为这是使用基本循环条件和其他使进一步处理变得多余的异常条件的方式。更重要的是,因为语法高亮会立即突出显示任何break
或continue
语句。无论如何,我认为你应该避免编写在其中无法立即发现break
的循环。 - cmaster - reinstate monicabreak
的观点,但在这个人为的例子中,搜索的结果是num == 500
。这也是文件被读取的原因。用简单的英语表达,条件应该是:“查看文件中是否有数字500。”我认为循环条件更清晰地表示了这种逻辑。而且我不认为它过于复杂——当然了。基本观点是,代码的逻辑应该易于理解,而break
可能会使其变得模糊,特别是如果“大多数时间”使用它。 - verbosebreak
本身有什么邪恶之处... - cmaster - reinstate monica
goto
,我没有发表任何言论,因为我并没有使用goto
。接着他们又禁用了continue
和break
,我也没有发表任何言论,因为那时我正在避免使用循环语句。最后他们禁用了我所需的代码语句... - Frédéric Hamidi