'do...while' vs. 'while'

新手上路,请多包涵

可能的重复:

While vs. Do While

什么时候应该使用 do-while 而不是 while 循环?

我已经编程了一段时间(2 年工作 + 4.5 年学位 + 1 年大学预科),而且我从未在编程入门课程中被迫使用 do-while 循环。如果我从来没有遇到过如此基本的事情,我越来越觉得我在做错误的编程。

难道是我没有遇到正确的情况?

有哪些示例需要使用 do-while 而不是 while?

(我的学习几乎都是 C/C++,而我的工作是 C#,所以如果有另一种语言绝对有意义,因为 do-while 的工作方式不同,那么这些问题并不适用。)

澄清一下……我知道 whiledo-while 之间的区别。 While 检查退出条件,然后执行任务。 do-while 执行任务然后检查退出条件。

原文由 mphair 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 565
2 个回答

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

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

} while (user says retry);

原文由 Bob Moore 发布,翻译遵循 CC BY-SA 2.5 许可协议

确实, do / while 循环非常罕见。我认为这是因为很多循环的形式

while(something needs doing)
    do it;

一般来说,这是一个很好的模式,并且它具有通常需要的特性,即如果不需要做任何事情,循环就会运行零次。

但是偶尔,无论如何,您肯定要至少进行一次循环旅行,这是有充分理由的。我最喜欢的例子是:将整数转换为十进制表示为字符串,即实现 printf("%d") 或半标准 itoa() 函数。

为了说明,这里是一个相当简单的实现 itoa() 。这 _不是_“传统”的表述。如果有人好奇,我将在下面更详细地解释它。但关键是它体现了规范算法,重复除以 10 以从右边挑选数字,并且使用普通的 while 循环编写……这意味着它有一个错误。

 #include <stddef.h>

char *itoa(unsigned int n, char buf[], int bufsize)
{
    if(bufsize < 2) return NULL;
    char *p = &buf[bufsize];
    *--p = '\0';

    while(n > 0) {
        if(p == buf) return NULL;
        *--p = n % 10 + '0';
        n /= 10;
    }

    return p;
}

如果您没有发现它,那么错误是 _如果您要求它转换整数 0 ,此代码什么都不返回 - 一个空字符串_。所以这是一个例子,当“无”可做时,我们 希望代码什么都不做——我们总是希望它至少产生一个数字。所以我们总是希望它至少完成一次循环。所以 do / while 循环就是票:

     do {
        if(p == buf) return NULL;
        *--p = n % 10 + '0';
        n /= 10;
    } while(n > 0);

所以现在我们有一个循环, 通常n 达到 0 时停止,但如果 n 最初为 0 - 如果您传入 0 - 它返回字符串 "0" ,根据需要。

正如所承诺的,这里有更多关于 itoa 函数的信息。你传递给它的参数是:一个 int 进行转换(实际上是一个 unsigned int ,这样我们就不必担心负数);要渲染到的缓冲区;以及该缓冲区的大小。它返回一个 char * 指向您的缓冲区,指向渲染字符串的开头。 (或者它返回 NULL 如果它发现你给它的缓冲区不够大。)这个实现的“非传统”方面是它从右到左填充数组,这意味着它不必在末尾反转字符串——这也意味着它返回给您的指针通常 不是 缓冲区的开头。所以你必须使用它返回给你的指针作为要使用的字符串;你不能调用它,然后假设你交给它的缓冲区是你可以使用的字符串。

最后,为了完整起见,这里有一个小测试程序来测试这个版本的 itoa

 #include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int n;
    if(argc > 1)
        n = atoi(argv[1]);
    else {
        printf("enter a number: "); fflush(stdout);
        if(scanf("%d", &n) != 1) return EXIT_FAILURE;
    }

    if(n < 0) {
        fprintf(stderr, "sorry, can't do negative numbers yet\n");
        return EXIT_FAILURE;
    }

    char buf[20];
    printf("converted: %s\n", itoa(n, buf, sizeof(buf)));

    return EXIT_SUCCESS;
}

原文由 Steve Summit 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题