“做…当”与“当”


86

可能的重复项:
While vs. While While
什么时候应该使用do-while而不是while循环?

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

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

有哪些示例需要使用“做一会儿”而不是“一会儿”?

(我的教育几乎都是用C / C ++进行的,而我的工作是使用C#的,因此,如果存在另一种语言绝对有意义,因为工作时间不同,那么这些问题就不适用了。)

为了澄清...我知道awhile和a之间的区别do-while。While检查退出条件,然后执行任务。do-while执行任务,然后检查退出条件。


42
值得一提的是,经过十年的编程生涯,我使用了一次或两次的do-while循环。
马特·格里尔

@Matt-那确实让我感觉好些。至少这意味着我并不孤单。
mphair,2010年

2
我将第二次给Matt,再加上十年左右的时间。我也很少使用do-while循环。
quentin-starin 2010年

许多重复。这里有一个链接到一群人:stackoverflow.com/questions/3094972/...
gnovice

3
正确的“主问题”似乎是stackoverflow.com/questions/224059/...
多纳尔研究员

Answers:


115

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

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

} while (user says retry);

3
因此,我认为这将遵循“我还没有遇到那种情况”的情况。
mphair,2010年

7
说实话,我很少碰到的时候我只需要使用do..while一种情况..
斯坦R.

1
也许有点短,但是鲍勃是对的。当您想至少运行一次代码块时,应使用do / while 。当您不知道是否要运行一次时,应使用while循环。就是说,我可以告诉您,凭借大约15年的开发经验,我使用while循环的次数是do / while循环的许多倍。
ConsultUtah 2010年

1
我也经常使用它们,尽管很少。片刻之后,它们通常也被重构为一个普通的while循环-只是因为它周围的区域发生了变化并做了一件事……同时比起最初更笨拙。
约书亚

2
这是相当普遍的。但是我不明白为什么在您的示例中您不使用while循环。而且我不知道为什么这个答案会被否决。

65

如果编译器不擅长优化,则do-while会更好。do-while仅具有一个条件跳转,而for和while具有条件跳转和无条件跳转。对于流水线化且不进行分支预测的CPU,这可能会在紧密循环的性能上产生很大差异。

而且,由于大多数编译器足够聪明地执行此优化,因此反编译代码中发现的所有循环通常都是在做的(如果反编译器甚至不愿意从反向本地geto重建循环)。


5
+1,用于将相关技术信息添加到循环形式之间的选择中。
quentin-starin 2010年

2
不仅过早而且无用。如果你真的想要一个while循环,即能力迭代0次,则必须在其循环在if带来在跳回来。
JeremyP

3
@杰里米:您所说的跳转不在循环内,它没有执行N次。
Ben Voigt

1
还要考虑Duff设备中do-while的经典用法(其中while循环被转换为展开的do-while,具有较大的步长和用于处理其余部分的跳转表),这大大减少了循环开销-在诸如memset的,memcmp,memcpy的它可能会增加吞吐量10的因子
奔福格特

@BenVoigt我知道您的评论是十年前的现在,但达夫设备不应该不很重要的警告被提及-它已经成为不太现代的编译器效率,因为现代的编译器通常可以智能地披简单循环本身是最佳的目标机器,尽管他们通常没有逻辑来弄清楚Duff装置的意图,因此也无法对其进行优化。这是关于为某些目标计算机而不是抽象的“足够高级的优化程序”优化代码的一课。
mtraceur

12

我已经在TryDeleteDirectory函数中使用了它。是这样的

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

真好 这是第一个包装在do ... while中有意义的示例。
约书亚

4
为什么/如何比标准更好while
Josh Stodola,2010年

该循环将始终执行一次,因此您可能需要执行一些操作,然后在失败时再次尝试。如果使用普通的while循环,则将在第一次迭代之前检查它是否失败。
NibblyPig

1
@SLC但是您是否仍要事先检查目录是否存在?
Josh Stodola,2010年

1
@Josh在此示例中,是。但是,如果您尝试打开与繁忙服务器的连接,则应先连接,然后查看响应是否为“繁忙”。如果是这样,您会在放弃之前再试几次。
NibblyPig 2010年

11

当您希望至少执行一次操作时,“做一会儿”很有用。作为使用do while vs. while的一个很好的例子,可以说您要进行以下操作:计算器。

您可以通过使用循环并在每次计算后检查此人是否要退出程序来解决此问题。现在您可以假设一旦打开程序,此人至少要执行一次此操作,那么您可以执行以下操作:

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

2
实际上,既然您提到了它,那么任何基于控制台的菜单驱动界面都可以在do ... while循环中很好地运行。例如,提示输入选项(一次一个键),仅在选择继续或退出时退出。
约书亚

7
continue是关键字; D
Thomas Eding

Atrinithis:大声笑...我滑了起来。感谢您在那里纠正我。

== true不需要。cont == true如果cont为true,则返回true。那完全没用。
Mr.DeleteMyMessages

11

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

正如其他所有人所说,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)

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

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

为循环创建新作用域的语言的附加好处是: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)

因此,这就是我的重点:在具有可空类型的语言中,这种情况initial_value == exit_value出现的频率要低得多,并且也许就是为什么您没有遇到这种情况的原因。我并不是说它永远不会发生,因为有时候函数会返回None以表示有效条件。但是,以我匆忙和简短考虑的观点,如果您使用的语言不允许使用表示以下内容的值,则这种情况还会发生很多:该变量尚未初始化。

这并不是一个完美的推理:实际上,既然空值是常见的,则它们只是构成变量可以采用的一组有效值中的另一个元素。但是实际上,程序员可以通过一种方式来区分处于明智状态(可能包括循环退出状态)的变量与处于未初始化状态的变量。


这是我在这里阅读的更有趣的回复之一。不错的贡献。
鲍勃·摩尔

这两个版本不相等。如果第一次读取返回None,则该while版本不会正确向响应缓冲区添加任何内容,但是您的do版本始终会添加一些内容。
大卫·斯通

@DavidStoneread()永远不会回来None。如果您使用的是库,则前提不适用(即,前哨值不在可能的检查值集中)。
熟练地

通过您的最新编辑,我看到的应该是''而不是None。某种评估为false的值。总结一下我对Pythonread函数的不熟悉。
大卫·斯通

@DavidStone我不明白。如果read()return '',则不会在字符串后附加任何内容,它为空。
熟练地

7

我在学校的时候经常使用它们,但是从那以后就很少使用了。

从理论上讲,当您希望循环主体在退出条件检查之前执行一次时,它们很有用。问题是,在少数情况下,我不想先执行检查,通常情况下,我希望退出检查位于循环主体的中间而不是最末端。在这种情况下,我更喜欢将著名for (;;)if (condition) exit;身体某个位置一起使用。

实际上,如果我对循环退出条件有些犹豫,有时我会发现for (;;) {}在需要的地方开始使用exit语句开始编写循环是很有用的,然后在完成后我可以看看它是否可以是“清除”,方法for是在括号内移动初始化,退出条件和/或递增代码。


5
出于好奇...为什么用“ for(;;)”代替“ while(true)”?
mphair,2010年

4
大概只是味道。我已经成长为等同for(;;)于“无限循环”,而while(true)我必须停下来思考一下。也许是因为在出现true。之前我正在编码C。过去TRUE,我们只作为一个宏,如果有什么问题,我必须说服自己自己,该宏还没有被重新定义0(发生了!)。这样for(;;)就没有机会了。如果您坚持使用while形式,我几乎宁愿看到while (1)。当然,然后有人可能会怀疑这是否不是字母l
TED

1
@mphair:是的,如果您注意到编辑器在斜体codeify文本时输入的文本,您可以直接在注释字段中直接输入。我已经看到一些人放入超链接,但是对我来说这有点过于刻板。
TED

2
@TED:我对loop-until-explicit-exit的首选表示法是“ do {} while(1);”。顺便说一句,在嵌入式系统中,我的常规循环范例是“ i = 10;执行{} while(-i);”。对于紧密循环,这比典型的for()要快得多;我认为,在不需要增加计数的情况下,始终如一地将其用作循环模式比在非关键性能的情况下任意使用for()更具可读性。
超级猫

2
加上while(1)和for(;;)的废话,我已经看到使用for(EVER)和EVER定义为;;的代码。
asr

6

在这种情况下,您总是需要运行一段代码,并且取决于结果,可能需要运行多次。同样可以通过规则while循环来产生。

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

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

6

do while是您是否要至少运行一次代码块。while另一方面,并​​非总是根据指定的标准运行。


5

就这么简单:

前置条件与后置条件

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

现在,您知道秘密了..明智地使用它们:)


1
就像我说的,我知道它们是如何工作的,我只是不确定在哪种情况下有意义。
mphair,2010年

逻辑上是,当您确定必须至少通过一次循环时才使用do {}。例如,如果您有一个在数组中查找元素的函数,并且之前已经放置了一个if array.IsEmpty()然后返回;。如果通过了该检查,则可以放心使用do {}。do-while也很容易想到,它是一个重复循环:“我吃直到满意为止”翻译为do(eat();} while(!satisfied();)。在循环之前测试条件被认为更安全。这就是为什么它被更频繁地使用的原因。
艾奥·保罗·皮劳

4

我看到这个问题已经得到了充分的回答,但是想添加这个非常具体的用例场景。您可能会开始更频繁地使用do...。

do
{
   ...
} while (0)

通常用于多行#define。例如:

#define compute_values     \
   area = pi * r * r;      \
   volume = area * h

这适用于:

r = 4;
h = 3;
compute_values;

-但是-有一个陷阱:

if (shape == circle)  compute_values;

因为它扩展为:

if (shape == circle) area = pi *r * r;
volume = area * h;

如果将其包装在do ... while(0)循环中,它将正确扩展为单个块:

if (shape == circle)
  do
  {
    area = pi * r * r;
    volume = area * h;
  } while (0);

2

到目前为止的答案总结了do-while的一般用法。但是OP要求一个示例,所以这里是一个示例:获取用户输入。但是用户的输入可能是无效的-因此您要求输入,请进行验证,如果有效则继续进行,否则请重复。

使用do-while时,您将获得输入,而输入无效。使用常规的while循环,您可以一次获得输入,但是如果输入无效,则可以一次又一次地获得输入,直到有效为止。不难看出,如果循环体变得越来越复杂,前者会更短,更优雅,更易于维护。


我认为我从未使用它们的原因是,我通常最终会告诉用户输入的内容有问题。这意味着条件将在循环的中心,而我将break在输入正确的情况下。
mphair,2010年

@mphair:实际上,对于这种情况,有时我可能更倾向于使用“ do {} while(0);”。循环,使用“ continue;” 如果用户的输入不可接受。如果只有一个问题和一条消息,请使用“ do {} while(1);” 和“休息”;效果很好,但是如果有多个原因要求重新输入,则“继续”;构造效果更好。
超级猫

2

我已经将它用于多次读取相同结构的阅读器。

using(IDataReader reader = connection.ExecuteReader())
{
    do
    {
        while(reader.Read())
        {
            //Read record
        }
    } while(reader.NextResult());
}

1

do while在读取文件开头的哨兵值时使用过a,但除此之外,我认为这种结构使用不太普遍也并不奇怪do-while-s确实是一种情况。

-- file --
5
Joe
Bob
Jake
Sarah
Sue

-- code --
int MAX;
int count = 0;
do {
MAX = a.readLine();
k[count] = a.readLine();
count++;
} while(count <= MAX)

1

这是我的理论,为什么大多数人(包括我)都喜欢while(){}循环来做do {} while():一个while(){}循环可以很容易地像do..while()循环那样执行,而相反是不正确的。while循环在某种程度上“更通用”。程序员也喜欢易于掌握的模式。while循环从一开始就说出它的不变性,这是一件好事。

这就是我所说的“更一般”的意思。采取这个do..while循环:

do {
 A;
 if (condition) INV=false; 
 B;
} while(INV);

将其转换为while循环很简单:

INV=true;
while(INV) {
 A;
 if (condition) INV=false; 
 B;
}

现在,我们采用模型while循环:

while(INV) {
     A;
     if (condition) INV=false; 
     B;
}

并将其转换为do..while循环,会产生这种怪异现象:

if (INV) {
 do
 {
         A;
         if (condition) INV=false; 
         B;

 } while(INV)
}

现在,我们在相对的两端进行了两次检查,如果不变,则必须在两个位置进行更新。在某种程度上,.... while就像您从未使用过的工具箱中的专用螺丝刀一样,因为标准螺丝刀可以满足您的所有需求。


1
替换为“ do {} while(x);” 循环成“ while(x);” 循环要求X要么是可以轻松“启动”的条件,要么在第一次通过时“自然”为真。对我来说,在循环之前启动语句意味着循环中的某些东西需要启动,而while(x){};“循环则意味着该循环可能执行零次。如果我希望一个循环至少执行一次,我
supercat”,2010年

1

我正在编程大约12年,而仅在3个月前,我遇到了一种情况,使用do-确实非常方便,因为在检查条件之前始终需要进行一次迭代。因此,猜测您的大事业已经到来了:)。


1
几乎每次我看到一个方法时...这都是由于对问题的理解不足,并且涉及到一些可怕的黑客。也有例外,但总的来说,如果您有能力做......,则应重新考虑自己的工作... :-)
Brian Knoblauch

2
如果您在正确的位置,那么do-while将被排除在所有编程语言之外,以免使程序员感到困惑:)。
Narek

@Narek:距您撰写本文已有七年了,您是否有更多情况下do while没有遗憾的更好的解决方案?
chqrlie

是的,可能还有一个时间:D
Narek

1

我无法想象如果没有使用 do...while循环,。

现在在另一台监视器上有一个,该程序中有多个这样的循环。它们都是以下形式:

do
{
    GetProspectiveResult();
}
while (!ProspectIsGood());

1

这是服务器/消费者中很常见的结构:

DOWHILE (no shutdown requested)
   determine timeout
   wait for work(timeout)
   IF (there is work)
      REPEAT
          process
      UNTIL(wait for work(0 timeout) indicates no work)
      do what is supposed to be done at end of busy period.
   ENDIF
ENDDO

REPEAT UNTIL(cond)作为一个do {...} while(!cond)

有时,等待工作(0)可能会在CPU上更便宜(即使取消超时计算也可能是非常高的到达率的一种改进)。此外,有许多排队理论结果使繁忙时段的服务人数成为重要的统计数据。(例如,参见Kleinrock-第1卷。)

类似地:

DOWHILE (no shutdown requested)
   determine timeout
   wait for work(timeout)
   IF (there is work)
      set throttle
      REPEAT
          process
      UNTIL(--throttle<0 **OR** wait for work(0 timeout) indicates no work)
   ENDIF
   check for and do other (perhaps polled) work.
ENDDO

check for and do other work主循环中放置昂贵的代码,或者不支持有效waitany(waitcontrol*,n)类型操作的内核,或者优先队列可能使其他工作耗尽而将节流阀用作饥饿控制的情况。

这种类型的平衡看似很糟,但可能是必要的。盲目使用线程池将完全抵消使用带有专用队列的看守线程的性能优势,因为该队列具有高更新速率,复杂的数据结构,因为使用线程池而不是看守线程将需要线程安全的实现。

我真的不想辩论有关伪代码(例如,是否应在UNTIL中测试请求的关闭)或看守线程与线程池的关系-但这只是为了说明特定的用例,控制流结构。


1

这是我的个人看法,但是这个问题是基于经验的答案:

  • 我从事C语言编程已有38年了,并且从未在常规代码中使用do/while循环。

  • 这种构造的唯一引人注目的用途是在宏中,它可以通过一个宏将多个语句包装为一个语句 do { multiple statements } while (0)

  • 我看到过无数个带有虚假错误检测或冗余函数调用的do/while循环示例。

  • 我对此观察的解释是,程序员在根据do/while循环进行思考时往往会错误地建模问题。他们要么错过了重要的结束条件,要么错过了移至结尾的初始条件的可能失败。

由于这些原因,我开始相信do/while循环中存在错误,并且我经常向新手程序员挑战,向我展示do/while不能在附近发现bug循环。

这种循环很容易避免:使用afor (;;) { ... }并在适当的地方添加必要的终止测试。这种测试很常见,这是很常见的。

这是一个经典的例子:

/* skip the line */
do {
    c = getc(fp);
} while (c != '\n');

如果文件不以换行符结尾,则将失败。这种文件的一个简单例子是空文件。

更好的版本是这样的:

int c;  // another classic bug is to define c as char.
while ((c = getc(fp)) != EOF && c != '\n')
    continue;

或者,此版本还隐藏c变量:

for (;;) {
    int c = getc(fp);
    if (c == EOF || c == '\n')
        break;
}

尝试while (c != '\n');在任何搜索引擎中搜索,您会发现诸如此类的错误(已于2017年6月24日收回):

ftp://ftp.dante.de/tex-archive/biblio/tib/src/streams.c中,functiongetword(stream,p,ignore)具有do/while并至少确定有两个bug:

  • c被定义为char
  • 存在潜在的无限循环 while (c!='\n') c=getc(stream);

结论:避免do/while循环并在看到错误时查找错误。


1
我更喜欢避免while() {}循环,因为它们在初始检查方面更安全,因此往往使您“脑筋小”,懒于思考更好的算法,进行了大量不必要的错误检查,依此类推。等等。“缺乏do{}while()使用”是错误(无脑)或新手程序员的迹象,会产生较低的质量和较慢的代码。因此,我首先问自己:“这是否完全是while(){}情况?” 如果不是,尽管可能需要更多思考和输入数据准确性,我还是会尝试编写do while循环
xakepp35

我理解您的回答,但我可以想到一些可能会更好的方案。请在以下时间查看:prnt.sc/v2zy04或在以下时间查看:prnt.sc/v2zyka。我从没来过程序员,但是在那儿找不到bug。很明显,“ do while”更干净,因为它不需要对while进行额外检查就可以进入循环。如果我们正在谈论优化代码,那我说那很干净。
Roy Berris

@RoyBerris:您的示例很有趣。在C程序中,循环内使用的函数将需要进行额外的测试,以确保它们不会失败。这将增加额外的混乱和breakreturn声明。将do/while循环变成一个for(;;)循环,恕我直言。我对这一说法的排斥类似于我strncpy() 即使在极少数情况下也拒绝使用它,因为那将是正确的工具:不要让随便的读者想象这些构造是无害的,因为在大多数情况下,它们是难以发现错误的来源。
chqrlie

@chqrlie看到原始答案是关于任何C语言的,我猜两个答案都可以。C#比它们的前任产品“节省很多”,因此从技术上讲,do while会更快。
Roy Berris

0

while循环检查循环之前的条件,do...while循环检查循环之后的条件。这是有用的,如果您希望将条件基于循环运行的副作用,或者像其他海报所说的那样,如果您希望循环至少运行一次。

我知道您来自哪里,但这do-while是大多数人很少使用的东西,而且我从未使用过自己。你没有做错。

你没有做错。这就像在说某人做错了,因为他们从未使用过byte原语。只是不是那么常用。


0

我遇到的使用do/while循环的最常见情况是在一个小的控制台程序中,该程序基于某些输入运行,并且会重复用户喜欢的次数。显然,控制台程序不运行就没有意义。但超出第一次取决于用户-因此do/while而不是while

如果需要,这允许用户尝试一堆不同的输入。

do
{
   int input = GetInt("Enter any integer");
   // Do something with input.
}
while (GetBool("Go again?"));

我怀疑是软件开发人员使用do/while这几天越来越少了,现在,几乎在阳光下每一个程序都有某种形式的GUI。使用控制台应用程序更有意义,因为需要不断刷新输出以提供说明或提示用户新信息。相比之下,使用GUI时,向用户提供该信息的文本只能放在表单上,​​而无需以编程方式重复。


0

读取文件时,我一直使用do-while循环。我处理许多文本文件,这些文件的标题中包含注释:

# some comments
# some more comments
column1 column2
  1.234   5.678
  9.012   3.456
    ...     ...

我将使用do-while循环读取“ column1 column2”行,以便我可以查找感兴趣的列。这是伪代码:

do {
    line = read_line();
} while ( line[0] == '#');
/* parse line */

然后,我将进行一个while循环以读取文件的其余部分。


如果您只是在主while循环中if (line[0]=='#') continue;read_line调用之后添加注释,则在文件中任何位置支持注释都是微不足道的(并总体上简化了代码)...
R .. GitHub停止帮助ICE 2010年

我看不到如何执行您的建议以查找标题。(当当,无法找出如何格式化注释中的代码,请帮助!)header = false; while(!header){line = read_line(); 如果(line [0] =='#')继续;标头= true; }这对您来说更清晰/更简单?
飞行

0

作为一名Geezer程序员,我的许多学校编程项目都使用文本菜单驱动的交互。几乎所有人都对主要过程使用了类似于以下逻辑的内容:

do
    display options
    get choice
    perform action appropriate to choice
while choice is something other than exit

从上学开始,我发现我更频繁地使用while循环。


0

当我们查看结果集时,我所看到的应用程序之一就是在Oracle中。

有了结果集后,您首先要从中进行获取(do),然后从该点开始进行获取。检查获取是否返回一个元素(找到元素时)。提取”的实现。


0

我在用于返回utf-8字符串中下一个字符位置的函数中使用了它:

char *next_utf8_character(const char *txt)
{
    if (!txt || *txt == '\0')
        return txt;

    do {
        txt++;
    } while (((signed char) *txt) < 0 && (((unsigned char) *txt) & 0xc0) == 0xc0)

    return (char *)txt;
}

请注意,此功能是从头脑中编写的,未经测试。关键是,无论如何,您都必须执行第一步,并且必须先进行评估,才能评估条件。


那是一种讨厌的写作方式*(unsigned char *)txt-0x80U<0x40
R .. GitHub停止帮助ICE,2010年

0

任何类型的控制台输入都可以与do-while一起使用,因为您会第一次提示,并在输入验证失败时重新提示。


0

即使有很多答案,这也是我的看法。一切都归结为优化。我将展示两个示例,其中一个比另一个要快。

情况1: while

string fileName = string.Empty, fullPath = string.Empty;

while (string.IsNullOrEmpty(fileName) || File.Exists(fullPath))
{
    fileName = Guid.NewGuid().ToString() + fileExtension;
    fullPath = Path.Combine(uploadDirectory, fileName);
}

情况2: do while

string fileName = string.Empty, fullPath = string.Empty;

do
{
    fileName = Guid.NewGuid().ToString() + fileExtension;
    fullPath = Path.Combine(uploadDirectory, fileName);
}
while (File.Exists(fullPath));

因此,有两个将做完全相同的事情。但是有一个根本的区别,那就是while需要输入额外的语句才能输入while。这很丑,因为我们可以说Guid该类的每种可能情况都已经采用,除了一个变体。这意味着我将不得不循环5,316,911,983,139,663,491,615,228,241,121,400,000多次。每次我到达while语句的结尾时,都需要进行string.IsNullOrEmpty(fileName)检查。因此,这将占用一点点CPU工作量。但是,将这个非常小的任务乘以可能的组合Guid班级而我们谈论的是小时,天,月或额外时间?

当然,这是一个极端的示例,因为您可能不会在生产中看到此情况。但是,如果我们考虑使用YouTube算法,很可能他们会在已经获取某些ID的情况下遇到ID的生成。因此,可以归结为大型项目和优化。



-1

在研究适用于我遇到的情况的正确循环时,我遇到了这个问题。我相信这将完全满足一个常见的情况,在这种情况下,do .. while循环比while循环(C#语言,因为您声明这是您的主要工作)是更好的实现。

我正在根据SQL查询的结果生成字符串列表。我的查询返回的对象是SQLDataReader。该对象具有一个称为Read()的函数,该函数将对象前进到数据的下一行,如果还有另一行,则返回true。如果没有另一行,它将返回false。

使用此信息,我想将每一行返回到列表,然后在没有更多数据要返回时停止。Do ... While循环在这种情况下效果最好,因为它可以确保在检查是否有另一行之前将项目添加到列表中。在检查while(condition)之前必须完成此操作的原因是,当它进行检查时,它也会前进。在这种情况下使用while循环会由于特定功能的性质而使其绕过第一行。

简而言之:

在我的情况下,这是行不通的。

    //This will skip the first row because Read() returns true after advancing.
    while (_read.NextResult())
           {
               list.Add(_read.GetValue(0).ToString());
           }

   return list;

这将。

    //This will make sure the currently read row is added before advancing.
    do
        {
            list.Add(_read.GetValue(0).ToString());
        } 
        while (_read.NextResult());

    return list;

SQLDataReader的用法是嵌套循环。内部的调用,Read()并且应该是while循环,因为第一个Read()调用访问第一行。外部调用NextResult()并且应该是一个do-while,因为第一个结果数据集在第一次NextResult()调用之前是活动的。代码段没有多大意义,尤其是因为注释都与代码不匹配并且是错误的。
Ben Voigt

-1
Console.WriteLine("hoeveel keer moet je de zin schrijven?");
        int aantal = Convert.ToInt32(Console.ReadLine());
        int counter = 0;

        while ( counter <= aantal)
        {
            Console.WriteLine("Ik mag geen stiften gooien");
            counter = counter + 1;

您应该回答自己的问题,就像要回答别人的问题一样。包括说明和代码
Simon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.