7

当我还是大一的时候,我们的教练允许我们使用breakcontinue循环。那时我大部分时间都这样做,因为它终止/继续循环。现在我大二了,我的导师告诉我不建议使用break/ 。continue你能告诉我为什么吗?顺便说一句,什么会影响中断/继续?

4

3 回答 3

18

有些人认为控制流过于复杂是不好的,这意味着像break,continue和多个returns 之类的东西。原因不是技术性的,主要是复杂的控制流会使程序的验证、测试和推理变得更加困难。

然而,这在很大程度上取决于风格、个人品味和您的整体结构。使用小型、用途良好的功能,拥有多个可能的流程可能几乎没有害处。特别是在 C++ 中,提前退出是一种流行的习惯用法,通常可以使代码更容易理解。

于 2013-09-03T09:51:39.550 回答
5

至少在 C 中,您不应该使用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);

循环条件本身可以准确地告诉读者您的代码要做什么,这使得它更容易快速理解。此外,作为奖励,您节省了几行代码。

现在想象一个更复杂的whilefor循环,其中break深埋在循环体内。很容易看出为什么试图找到break触发器会变得烦人。拥有一个结构合理的循环条件更多,嗯,自我记录。

当然,在某些情况下breakcontinue实际上是编写代码的好方法。例如,如果循环应该结束的条件可能发生在循环执行的中间,并且循环内部有很长的语句集,并且执行这些语句会增加处理时间而没有完成任何有用的事情,当然,继续使用break. 但这些情况是例外,而不是“大多数时候”。

于 2013-09-03T10:29:03.497 回答
5

我见过的大多数关于代码正确性的推理逻辑都假设单入口/单出口。如果你的循环用breakand填充continue,就不可能知道你的循环不变量是否得到满足,或者你是否总是取得进展(所以循环不会是无止境的)。(请注意,do { ... } while (...);循环也受此影响;循环不变量不是第一次建立的,这可能会导致一些意外。)

在您想使用breakor 的大多数情况下continue,您可能使循环(以及包含它的函数)太大且太复杂。

有些人会争辩说:

for (;;) {
    //  ...
    if ( conditionMet ) {
        break;
    }
    //  ...
}

对于经典循环和半成语来说是可以接受的;毕竟,它是单入口/单出口,即使出口不是我们所期望的(并且在阅读代码时很难找到)。关于循环不变量的问题仍然存在;之前没有遇到过if,至少是第一次遇到。通常,更好的解决方案是将测试之前的代码放入一个单独的函数中,该函数返回conditionMet,并使用:

while ( doLoopPrefix() ) {
    doLoopSuffix();
}

(一般来说,如果你的循环超过三四行,你应该重构。除非它包含一个switch 语句,而且有很多情况。)

于 2013-09-03T11:40:06.510 回答