对于(;;)或while(true),哪个是正确的C#无限循环?[关闭]


97

回到我的C / C ++时代,将“无限循环”编码为

while (true)

感觉更自然,对我而言似乎更明显

for (;;)

在1980年代后期与PC-lint的相遇以及随后的最佳实践讨论打破了我的这种习惯。从那以后,我使用for控制语句对循环进行了编码。今天,很长一段时间以来的第一次,也许是我作为C#开发人员的第一个无限循环需求,我正面临着同样的情况。其中一个是正确的,另一个是不正确的吗?


5
在不到两分钟的时间内得到四个相同的答案。不错。
Jon B

5
您可以通过展开无限循环来避免整个宗教争论。不应该花很长时间...
Stephen Darlington

7
出于好奇:为什么在C / C ++中for(;;)更好?
Vilx-

6
我记得@Vilx,旧的编译器过去常常使用for(;;)来编写代码,而while(1)来编写。我敢肯定,任何像样的现代编译器都会输出几乎相同的代码。
斯蒂芬·达灵顿,

4
基于斯蒂芬和塞里奥的评论:1. while(true)需要一个条件。for(;;)因此,它是无条件重复的无限循环的更好表示。2.旧的未优化的编译器可能实际上已经评估了(true)循环。3. C是电传打字机,300波特终端和1个字符的变量名时代的一种极简主义语言。在每个按键都很重要的环境中,for(;;)比短很多while(true)
理查德·丁沃尔

Answers:


124
while(true)
{

}

一直是我使用过的东西,我见过其他人使用的东西也必须手动中断。


@RSolberg-这是彼此之间在几秒钟内提供的两个类似响应之间的一次折腾。亚当的后续评论使我接受了基于用法而不是惯例的答案。
鲍勃·考夫曼

1
同时可以手动破坏
艾伦·赖斯2009年

2
不幸的是,这个答案不能回答问题。正确答案是“两者都是正确的”。
David R Tribble 2013年

2
@Loadmaster:这取决于您对“正确”的定义(或者,您所追求的是哪种“正确性”)。
亚当·罗宾逊

314

C#编译器将转换

for(;;)
{
    // ...
}

while (true)
{
    // ...
}

进入

{
    :label
    // ...
    goto label;
}

两者的CIL相同。大多数人发现while(true)更容易阅读和理解。for(;;)相当神秘。

资源:

我将.NET Reflector弄得更加混乱,并且在Visual Studio中使用“优化代码”对两个循环进行了编译。

这两个循环都编译成(使用.NET Reflector):

Label_0000:
    goto Label_0000;

猛龙应尽快进攻。


7
是的,只是仔细检查了一下,所有的IL代码都一样,这应该是IMO可接受的答案:)
艾伦·赖斯

63
+1为xkcd参考
Ikke

4
要学究,编译器并不会改变一个命题形式到另一个; 而是,它为两个语句生成相同的代码。该代码与goto语句btw 相同,这不足为奇。
David R Tribble

1
然后转到被转换为JMP指令..
马可M.

25
所以显然goto LOOP是正确的C#无限循环:)
Dustin Getz

61

我认为这可能更易于阅读,并且绝对是C#中使用的标准:

while(true)
{
   //Do My Loop Stuff
}

19
@voyager:1不能替代C#中的'true'。
亚当·罗宾逊

17
请注意,当(1)是无效的C#:常数1不能被转换成布尔
Vinko Vrsalovic

4
while(1)在C#中无效,因为1不是bool
帕维尔·米纳夫

47

喘气,使用:

while (!false)
{

}

或者如jsight所指出的,您可能需要双重确定:

while (!false && true)
{
}

在人们大喊大叫之前,我检查的都是相同的CIL代码:)


有史以来最好的答案。
拉里

38

重现一些老笑话:

  1. 不要使用“ for (;;) {}”,它会使语句哭泣。
  2. 当然,除非您是“ #define EVER ;;”。

25
还是#define ever (;;)我认为更具可读性。for ever {}
克里斯·卢茨

1
我没想到您可以在C#中做一个#define(;;),但这个笑话很有趣:)
艾伦·赖斯

1
啊。我在OS X上编写C语言。我不知道C#预处理器是如何被cast割的。我什至不确定我是如何开始阅读这个问题的,我将C#作为忽略的标记……
Chris Lutz

C#预处理器并不是真正的预处理器,至少就C,C ++,PL / 1甚至宏汇编程序而言不是。它仅允许您通过定义/取消定义预处理程序符号来启用或禁用代码块。
David R Tribble

6
甚至更好:#define forever while(true);)
Roberto Bonvallet 09年

26

如果您想去老学校,C#仍支持goto:

STARTOVER:  
    //Do something
    goto STARTOVER;

对于真正的无限循环,这是转到命令。=)



6
我赞成将其从负面评分恢复为零,但这仅仅是因为它具有幽默感。嘿,无论如何,所有循环都会被编译成JMP汇编器操作码,对吗?
David R Tribble

@Loadmaster:谢谢,我只是将它作为另一种选择扔掉了,不一定支持它。
JohnFx

2
@serhio:更重要的是,避免在阅读某处内容时会失控语言结构。没有语言元素本身就是坏的,只能以坏的方式使用。
JohnFx

2
@serhio:我已经看到几乎每一个可能的关键词都在反自然。它不是语言元素,而是程序员。无论如何,正如我先前的评论中所指出的那样,我并不赞成。我只是为了完整性和幽默感而包括了它。
JohnFx


10

在那些我需要一个真正的无限循环的情况下,我一直使用

while(true) {...}

它似乎比空的for语句更好地表达意图。


10

就我个人而言,我一直偏爱for(;;)准确无误的原因,因为它没有条件(与之相对的条件while (true)总是真实的)。但是,这确实是一个非常次要的风格要点,我认为这两种方法都不值得争论。我还没有看到强制或禁止这两种方法的C#样式指南。


在.NET中不值得,当编译器在有条件的情况下将您的(可读性差)转换无条件
serhio 2010年

3
@serhio:请解释“编译器转换为...”的含义while。就程序员而言,编译器将高级代码转换为IL。IL 中没有while(或for)循环,只有标签和gotos。
帕维尔·米纳夫

1
请参阅Pierre-Alain Vigeant的答案。
serhio

3
他的答案可以更好地改写为“编译器为两者生成相同的IL”(您真的不知道它是否以及何时在AST级别上转换任何东西,无论如何它都是实现细节)。无论如何,这并不能解释为什么它“在.NET中不值得”。C ++,Java也是如此……
Pavel Minaev 2010年

6

我个人更喜欢这种for (;;)习惯用法(从C / C ++的角度来看)。虽然我同意while (true)从某种意义上讲,它更具可读性(即使在C / C ++中,这也是我以前使用的方式),但我转向使用该for惯用法,因为:

  • 它脱颖而出

我认为循环不会终止(以正常方式)这一事实值得“大呼小叫”,而且我认为这样for (;;)做还可以。


最后,使用它,我们将等待程序编译(从for => while进行编译转换)的时间多一点
serhio 2010年

3
@serhio:并非如此。它不改变从中forwhile。对于for (;;){}while (true){},它都会生成新while(true){}代码。看到这个答案
wchargin

6

建议使用C 的原始K&R书籍,C#可以从中追溯其起源

for (;;) ...

对于无限循环。它是明确的,易于阅读的,并且具有悠久而悠久的历史。

附录 (2017年2月)

当然,如果您认为这种循环形式(或任何其他形式)太含糊,可以随时添加一个注释

// Infinite loop
for (;;)
    ...

要么:

for (;;)    // Loop forever
    ...

1
是的,但这是针对C的,而不是针对C#的。
serhio 2010年

1
它适用于C#。和C#语言,导出(间接地)从C
戴维r特里布尔

4
8年后,您决定更新答案。尼斯
Metoniem '17

4

它应该while(true)不是while(1),所以while(1)在C#中是不正确的,是;)


2

另一种选择是,无论如何,拥有无限循环通常都是不好的做法,因为除非应用程序真正永久运行,否则它需要退出条件。但是,如果这是用于巡航导弹,我可能会接受明确的退出条件。

虽然我喜欢这个:

for (float f = 16777216f; f < 16777217f; f++) { } 

2
-1:并不是每个人都能理解您的“无限循环”阅读代码,也许有人会认为这是一个错误并尝试“修复”它……
serhio 2010年

在C#f < 16777217f中始终是false...,所以它永远不会循环。
NetMage

2

我更喜欢“识字”代码。在实践中,我更有可能做这样的事情:

bool shouldContinue = true;
while (shouldContinue)
{
    // ...

    shouldContinue = CheckSomething();
}

1
啊。实际上,这是一个do ... while()变相的循环。我只花了几秒钟就看到了。如果您编写了一个do ... while()循环,那将立即变得清晰起来。-1
sbi

为什么在可以使用while(true)时浪费时间和资源来声明变量?我认为这没有任何意义
-waqasahmed

我发现它更具可读性,特别是如果您可以附加特定的有意义的标志,例如,“ while(!this.canceled)”表示取消是停止循环的唯一方法,“ while(!processExited)”表示循环应该运行,直到外部流程消失为止。等等。有许多可以说是“浪费资源”的事情,以简化可维护性或可读性为名,这绝对是正确的选择。“ while(true)”并不是很糟糕,但是根据我的经验,通常有更好的方法。
bobbymcr

1
+1。在大多数情况下,真正的无限循环实际上并没有发生,并且您确实希望停止某些条件(例如,打印机着火时)。
Lie Ryan

1
…在这种情况下,您应该使用break
Ry-


1

如果您正在打代码,我建议for(;;)。除此之外,它while(true)具有相同的含义并且看起来更加直观。无论如何,大多数编码人员都可能会理解这两种变化,因此这并不重要。使用最舒适的东西。


2
如果您正在打高尔夫球,那么C#还是错误的语言。
SingleNegationElimination

1

我要说的唯一原因for(;;)是由于CodeDom的限制(虽然无法使用CodeDom声明循环,而for循环被视为迭代循环的更一般形式)。

除了for可以将循环实现既可以用于普通代码又可以用于CodeDom生成的代码这一事实之外,选择这是一个很宽松的理由。也就是说,它可以更标准。

请注意,您可以使用代码段创建一个while循环,但是整个循环需要是一个代码段...


1

两者具有相同的功能,但人们通常更喜欢while(true)。感觉很容易阅读和理解...


0

对于while循环,任何始终返回true的表达式都应该可以。

例:

1==1 //Just an example for the text stated before 
true

当true同样有效时,为什么还要强迫它进行1 = 1的比较呢?使用计算出的表达式感觉就像定义一个常数一样愚蠢,例如NUMBER_OF_ARMS = 598-3596;
JohnFx

它是在代码之前陈述答案的一个示例:)
乔治

0

while(true)任何语言中的代码可读性方面,我认为都更有意义。就计算机的外观而言,在当今非常高效的编译器和解释器社会中,应该没有任何区别。

如果有任何性能差异,我相信对MSIL的转换将优化。您可以检查是否确实要这样做。

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.