'做'而'与'同时'

mph*_*air 75 c c# c++ while-loop do-while

可能重复:
虽然与Do同时
我应该何时使用do-while而不是while循环?

我已经编程了一段时间(2年的工作+ 4.5年的学位+ 1年的大学预科课程),而且我从未使用过do-while循环而不是被迫参加编程入门课程.如果我从未遇到过如此根本的事情,我会越来越感觉我编程错了.

可能是因为我没有遇到正确的情况吗?

有哪些例子需要使用do-while而不是一段时间?

(我的学校教育几乎都是用C/C++编写的,我的工作是在C#中,所以如果有另一种语言绝对有意义,因为do-whiles的工作方式不同,那么这些问题并不适用.)

澄清......我知道a while和a 之间的区别do-while.在检查退出条件然后执行任务时.do-while执行任务然后检查退出条件.

Bob*_*ore 100

如果你总是希望循环执行至少一次.这并不常见,但我会不时使用它.您可能想要使用它的一种情况是尝试访问可能需要重试的资源,例如

do
{
   try to access resource...
   put up message box with retry option

} while (user says retry);
Run Code Online (Sandbox Code Playgroud)

  • 老实说,当我只需要使用do..while时,我很少遇到这种情况. (5认同)
  • 所以我想这将遵循"我没有遇到过这种情况". (3认同)
  • 这很常见.但我不明白为什么在你的例子中你不会使用while循环.我不明白为什么这个答案被赞成. (2认同)

Ben*_*igt 61

如果编译器不能胜任优化,那么do-while会更好.do-while只有一个条件跳转,而for和while则有条件跳转和无条件跳转.对于流水线且不进行分支预测的CPU,这可能会对紧密循环的性能产生很大影响.

此外,由于大多数编译器都足够智能来执行此优化,因此在反编译代码中找到的所有循环通常都是do-while(如果反编译器甚至不愿意从后向本地gotos重建循环).

  • +1我想知道这是否被认为是过早的优化 (11认同)
  • +1用于将相关技术信息添加到循环表单之间的选择. (4认同)
  • @Jeremy:你说的跳跃是在循环之外,它没有执行N次. (3认同)
  • 不仅过早而且无用.如果你真的想要一个while循环,即迭代0次的能力,你必须将循环包含在一个带回来的if中. (2认同)

小智 11

当你想要至少执行一次某事时,同时有用.至于使用do while while while的一个很好的例子,假设您想要做以下事情:计算器.

您可以通过使用循环来检查这一点,并在每次计算后检查该人是否要退出程序.现在你可以假设一旦打开程序,这个人想要至少做一次这样做,你可以做以下事情:

do
{
    //do calculator logic here
    //prompt user for continue here
} while(cont==true);//cont is short for continue
Run Code Online (Sandbox Code Playgroud)

  • `continue`是关键字; D (7认同)
  • 实际上,既然您提到了它,任何类型的基于控制台的菜单驱动界面在 do...while 循环中也能做得很好。例如,提示选项(一次一个键),只有在他们选择继续或退出时才退出。 (2认同)

Cha*_*dam 11

我在TryDeleteDirectory函数中使用过它.就是这样的

do
{
    try
    {
        DisableReadOnly(directory);
        directory.Delete(true);
    }
    catch (Exception)
    {
        retryDeleteDirectoryCount++;
    }
} while (Directory.Exists(fullPath) && retryDeleteDirectoryCount < 4);
Run Code Online (Sandbox Code Playgroud)

  • 为什么/如何比标准`while`更好? (4认同)

det*_*tly 10

这是一种间接的答案,但这个问题让我思考它背后的逻辑,我认为这可能值得分享.

正如其他人所说的那样,do ... while当你想要至少执行一次身体时,你会使用一个循环.但在什么情况下你想这样做?

好吧,我能想到的最明显的一类情况是,检查条件的初始("未打底")值与您想要退出时的值相同.这意味着您需要执行一次循环体以将条件置为非退出值,然后根据该条件执行实际重复.程序员如此懒惰,有人决定将其包含在控制结构中.

因此,例如,从超时的串行端口读取字符可能采用这种形式(在Python中):

response_buffer = []
char_read = port.read(1)

while char_read:
    response_buffer.append(char_read)
    char_read = port.read(1)

# When there's nothing to read after 1s, there is no more data

response = ''.join(response_buffer)
Run Code Online (Sandbox Code Playgroud)

注意代码的重复: char_read = port.read(1).如果Python有一个do ... while循环,我可能会使用:

do:
    char_read = port.read(1)
    response_buffer.append(char_read)
while char_read
Run Code Online (Sandbox Code Playgroud)

为循环创建新范围的语言的附加好处:char_read不会污染函数名称空间.但请注意,有一种更好的方法可以做到这一点,那就是使用Python的None值:

response_buffer = []
char_read = None

while char_read != '':
    char_read = port.read(1)
    response_buffer.append(char_read)

response = ''.join(response_buffer)
Run Code Online (Sandbox Code Playgroud)

所以这就是我的观点的关键:在具有可空类型的语言中,情况initial_value == exit_value出现的频率要低得多,可能就是你没有遇到它的原因.我并不是说它永远不会发生,因为有时功能会返回None以表示有效状态.但是,在我匆忙和简要考虑的意见中,如果您使用的语言不允许表示的值,则会发生更多这种情况:此变量尚未初始化.

这不是完美的推理:实际上,现在空值很常见,它们只是形成变量可以采用的有效值集合中的另一个元素.但实际上,程序员有办法区分处于合理状态的变量,其中可能包括循环退出状态,并且处于未初始化状态.


T.E*_*.D. 7

我在学校的时候用了很多东西,但从那以后就没用了.

理论上,当您希望循环体在退出条件检查之前执行一次时,它们非常有用.问题是,对于我不想先检查的少数情况,通常我希望在循环体的中间而不是在最末端进行退出检查.在那种情况下,我更喜欢在身体for (;;)if (condition) exit;某个地方使用众所周知的.

事实上,如果我在循环退出条件上有点不稳定,有时我发现for (;;) {}在需要的时候开始将循环写为带有退出语句的循环很有用,然后当我完成时我可以看到它是否可以"通过移动初始化,退出条件和/或在for括号内增加代码来清理.

  • 出于好奇......为什么"for(;;)"而不是"while(true)"? (5认同)
  • 可能只是味道.我已经逐渐将`for(;;)`与"无限循环"等同起来,而`while(true)`我必须停下来思考.也许是因为我在有一个'真实'之前编码C. 回到那一天,我们只有'TRUE`作为一个宏,如果有什么东西是错误的,我必须说服自己,宏还没有被重新定义为'0`某种程度(它发生了!).用`for(;;)`就没有机会了.如果你坚持使用while形式,我几乎可以看到`while(1)`.当然有些人可能会怀疑这不是字母l ... (4认同)
  • @TED:我对 loop-until-explicit-exit 的首选表示法是“do{}while(1);”。顺便说一句,在嵌入式系统工作中,我的正常循环范式是“i=10; do {} while(--i);”。对于紧密循环,这比典型的 for() 快得多;我认为在不需要向上计数时始终将其用作循环模式比在非性能关键情况下任意使用 for() 更具可读性。 (2认同)
  • 添加到while(1)和for(;;)disusion,我看到代码使用for(EVER)与EVER定义为;; (2认同)

spi*_*non 6

do while如果你想至少运行一次代码块.while另一方面,根据指定的标准,并不总是运行.


Edw*_*eno 6

在这种情况下,您总是需要运行一段代码,并且根据其结果,可能需要更多次.同样可以使用常规while循环生成.

rc = get_something();
while (rc == wrong_stuff)
{
    rc = get_something();
}

do
{
    rc = get_something();
}
while (rc == wrong_stuff);
Run Code Online (Sandbox Code Playgroud)


Ioa*_*rau 5

就这么简单:

前提条件与后置条件

  • while(cond){...} - 前提条件,它仅在检查后执行代码.
  • do {...} while(cond) - postcondition,代码至少执行一次.

既然你知道秘密......明智地使用它们:)