“while (true) + break” 是否是不良的编程实践?

81

我经常使用这个代码模式:

while(true) {

    //do something

    if(<some condition>) {
        break;
    }

}   

另一位程序员告诉我这样做是不好的实践,建议我替换成更标准的:

while(!<some condition>) {

    //do something

}   
他的理由是你很容易“忘记break”并导致无限循环。我告诉他在第二个例子中,你同样可以添加一个条件永远不会返回true,因此也同样容易导致无限循环,所以两种方法都是同样有效的。
此外,当你有多个跳出循环的条件时,我通常更喜欢前一种方法,因为它使代码更易于阅读。
有谁能通过为其中一方添加证据来丰富这个论点?

2
如果我指出这个问题 http://stackoverflow.com/questions/212531/is-while-truebreakend-while-a-good-design 基本上是在问同样的事情,那么我会被视为一个脾气暴躁的人吗? - Jonathan Leffler
另一个类似的问题,有趣的答案:https://dev59.com/X3VC5IYBdhLWcg3wlyQo - Jim Nelson
23个回答

1

这取决于你想做什么,但一般来说我更喜欢将条件放在while循环中。

  • 它更简单,因为你不需要在代码中进行另一个测试。
  • 它更容易阅读,因为你不必在循环内部寻找break。
  • 你正在重新发明轮子。while的整个意义是只要测试为真就执行某些操作。为什么要通过将break条件放在其他地方来破坏它呢?

如果我正在编写一个应该一直运行直到被杀死的守护进程或其他进程,我会使用while(true)循环。


1

如果只有一个(且仅有一个)非异常的中断条件,将该条件直接放入控制流结构(while)中是更可取的。看到 while(true) { ... } 会让我作为代码阅读者认为没有简单的方法来枚举中断条件,并让我想“仔细查看这个并仔细考虑中断条件(在当前循环之前设置了什么,在上一个循环中可能设置了什么)”

简而言之,在最简单的情况下,我同意你的同事,但 while(true){ ... } 并不罕见。


1

我认为使用 "while(true)" 的好处可能在于让多个退出条件更容易编写,特别是如果这些退出条件必须出现在代码块的不同位置。然而,对我来说,当我必须运行代码以查看代码如何交互时,这可能会导致混乱。

个人而言,我会尽量避免使用 while(true)。原因是每当我回顾之前编写的代码时,我通常发现我需要弄清楚它何时运行/终止,而不仅仅是它实际执行了什么操作。因此,首先定位“breaks”对我来说有点麻烦。

如果需要多个退出条件,我倾向于将条件确定逻辑重构为单独的函数,以使循环块看起来更清晰、更易于理解。


1

不,这并不是坏事,因为当你设置循环时可能并不总是知道退出条件,或者可能有多个退出条件。但是,这需要更多的注意才能防止无限循环。


1

完美顾问的回答:这取决于情况。在大多数情况下,正确的做法是使用while循环。

while (condition is true ) {
    // do something
}

或者使用类C语言中的“重复直到”语句

do {
    // do something
} while ( condition is true);

如果这两种情况都适用,就使用它们。
有时,比如在服务器的内部循环中,您确实希望程序一直运行,直到外部某个东西打断它。(例如考虑一个httpd守护进程--除非它崩溃或被关闭,否则它不会停止。)
只有在这种情况下才使用while(1):
while(1) {
   accept connection
   fork child process
}

最后一种情况是在终止函数之前想要执行某些部分的罕见情况。在这种情况下,请使用:

while(1) { // or for(;;)
   // do some stuff
   if (condition met) break;
   // otherwise do more stuff.
}

0

他可能是正确的。

在功能上,两者可能是相同的。

然而,为了代码的可读性和理解程序流程,使用 while(condition) 更好。使用 break 有点像使用 goto。而 while(condition) 对于继续循环的条件非常清晰明确等等。这并不意味着 break 是错误的,只是可读性可能会差一些。


0

我想到了使用后一种结构的几个优点:

  • 不需要在循环代码中寻找breaks,更容易理解循环正在做什么。

  • 如果您不在循环代码中使用其他breaks,则循环中只有一个退出点,即while()条件。

  • 通常会减少代码量,从而提高可读性。


0

我更喜欢使用 while(!) 的方法,因为它更清晰、更直接地传达了循环的意图。


0

问题不在于while(true)这部分,而是你必须要使用break或goto来跳出循环。break和goto并不是真正可接受的流程控制方法。

我也不太明白这样做的意义所在。即使在一个循环程序中,你至少可以设置一个名为Quit的布尔变量,将其设置为true以正确地退出循环,例如像while(!Quit)这样的循环...而不是在某个任意点调用break并跳出循环。


为什么“break”在很多编程语言中都存在,即使它“并不是真正可接受的”?毫无疑问,“break”确实有其用途。 - reggaeguitar

0

像使用循环语句:

while(1) { do stuff }

在某些情况下是必要的。如果您进行嵌入式系统编程(比如类似于PICs、MSP430和DSP编程的微控制器),那么几乎所有的代码都将包含在while(1) 循环中。当对DSP进行编程时,有时您只需要一个 while(1){} ,其余的代码都是中断服务程序(ISR)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接