何时使用do-while循环?

14

在何种情况下,do-while循环比其他类型的循环更好?有哪些常见的情况其优于其他循环?

我明白do-while的功能,但不知道何时使用它。


我确定我以前见过这个问题。虽然找不到重复的内容。 - Nosredna
1
@Hardwareguy 一点也没有。我在做某事时突然想到,整个项目中我都没有用到它。 - Alex S
是的,我发现我几乎从不使用它。即使在某些情况下,我知道循环必须在检查条件之前完成一次迭代,但第一次迭代在某种程度上是一个特殊情况,因此将其放在循环块之外会更有意义。 - Sean
你应该澄清这是一个在结尾处测试的循环。VB6/VBA有一个“Do While...Loop”语法,在循环开始时进行测试。 - DJ.
2
相关问题:https://dev59.com/jXNA5IYBdhLWcg3wWseK 和 http://stackoverflow.com/questions/390605/while-vs-do-while - Adam Rosenfield
13个回答

57

当你需要至少执行一次某项任务,但在开始循环之前不知道要执行多少次。


1
我自己没法说得更简单了。+1 - Gab Royer
但是有时候你不需要使用do...while来做到这一点,例如像while(input.hasNext())这样的情况,所以这并不一定是一个严格的规则。 - Thomas Owens
1
@Thomas Owens:好的,你可以用简单的for语句完成任何需要的循环,所以你不一定需要do/while,但我认为如果你想表达意图,do/while正好适合这种情况。 - Brian Rasmussen
“初始化循环”是指:1. 在do ... while语句之外初始化变量,还是2. 在do ... while语句体内初始化变量? - modeller

4

通常情况下,这不是最佳选择,但在某些情况下会很有用,比如你必须至少执行一次某个操作,但之后的迭代取决于某些条件。

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

4

当需要处理某些操作,但第一次执行可能并不成功时,通常我会使用do-while语句。例如:

int x;
do
{
    x = random.next(100);
    cout << x << endl;
} while (x != 13);

在这种情况下,你开始使用的x并不重要,因为它会被覆盖。

4

还没有人提到它在C语言宏中的使用...

#define do_all(x) do{ foo(x); bar(x); baz(x); } while(0)

然后在代码中可以这样写:

do_all(a);
  • 关键在于它仅被执行一次,而宏调用末尾的分号完成了while(0);语句。

3

如果需要实现大量条件检查,比如在php中处理输入表单,我之前使用过它。虽然这可能不是最佳实践,但它比许多其他替代方案更易读:

do {
   if ( field1_is_invalid ) {
      $err_msg = "field1 is invalid"; break;
   }

   if ( field2_is_invalid ) {
      $err_msg = "field2 is invalid"; break;
   }

   .. check half a dozen more things ..

   // Only executes if all checks succeed.
   do_some_updates();

} while (false)

此外,我想这并不严格地算是一个循环。更像是一种避免使用GOTO的方法 :)

1
将相同的逻辑封装在一个函数中,并用返回值替换断点,这样不是更易读吗?您还可以在返回值中指示哪个检查出错了。 - shylent
@shylent - 是的,这样做可能会有影响,这也是我提到它可能不是最佳实践的原因。但有时候它还是很有用的。 - Eric Petroelje

2

当您希望在循环执行结束时检查状态时,这是合适的。因此,该循环将始终至少运行一次,然后它将验证是否应进一步迭代。


2

通常在需要用户输入一些值时,计数器变量基于输入值,你可以使用do-while循环。 //以下代码是用C++编写的。它要求用户输入一个数字,并重复直到用户输入的数字大于0。

do{
    cout << "Enter a Positive integer: ";
    cin >> num;
}while( num < 0 );

1

当你进行递归操作时,例如读取内部异常时,可能会出现另一种异常:

catch(Exception exc)
{
    Exception currentException = exc;
    do
    {
        Console.WriteLine(string.Format("{0}: {1}", currentException.GetType().Name, currentException.Message));
    } while((currentException = currentException.InnerException) != null);
}

1
当更合适的时候先执行某些操作然后评估布尔表达式...或者像Brian所说...当你需要至少执行一次操作时。这种语法将布尔表达式的评估移到循环之后而不是之前。

1
无论循环中的内容如何,都至少需要执行一次。

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