为什么使用for循环而不是while循环?

时间:2010-10-06 17:11:04

标签: loops coding-style control-flow

  

可能重复:
  Iterate with for loop or while loop?
  Loops in C - for() or while() - which is BEST?

何时应该使用for循环而不是while循环?

我认为以下循环是相同的,除了它们的语法。如果是这样,为什么选择一个而不是另一个呢?

int i;
for (i = 0; i < arr.length; i++) {
  // do work
}

int i = 0;
while (i < arr.length) {
  // do work
  i++;
}

28 个答案:

答案 0 :(得分:101)

在你的情况下,除了for循环中少一行代码之外,你获得的收益并不多。

但是,如果你这样声明循环:

for(int i = 0; i < x; i++)

您设法将i保留在循环范围内,而不是让它转义到代码的其余部分。

此外,在while循环中,您有3个不同位置的变量声明,条件和增量。有了for循环,它就在一个方便,易读的地方。

最后的想法:
一个更重要的说明。两者之间存在语义差异。虽然循环通常意味着具有无限次迭代次数。 (即直到文件被读取..无论其中有多少行),for循环应具有更确定的迭代次数。 (循环遍历集合中的所有元素,我们可以根据集合的大小对其进行计数。)

答案 1 :(得分:85)

选择for优于while有一个原因:可读性。

通过使用for循环,您明确表示您的意图是执行某些需要初始化,“步进”操作和完成条件的操作。

另一方面,对于while,您只是说您需要完成条件。

答案 2 :(得分:35)

当我不一定需要计数器时,我会使用'while',例如当您从文件中读取并且您正在等待达到EOF时。在这种情况下,'for'可能不是最好的选择。当你浏览阵列上的项目时,我宁愿使用'for',因为它更能传达意图。

答案 3 :(得分:27)

for()和while()循环之间的一个显着区别是while()循环中的“continue”语句将分支到循环的顶部,而for()循环中的一个将分支到for()子句的第三部分[条件之后的一部分,通常用于碰撞变量]。

答案 4 :(得分:16)

作为一名教师,我一直在思考各种形式和形式;我的建议总是归结为

  • for - 循环用于计数。数数,倒计时。
  • while / do-while构造适用于所有其他条件。 c!=EOFdiff<0.02等 迭代器/枚举器是非常适合for循环的计数器。

即。你的int=0; while( ... )对我来说很可怕。

答案 5 :(得分:15)

为什么选择可口可乐而不是百事可乐?

在WHILE和FOR循环之间,您可以互换使用它们。要成为纯粹主义者,您可以根据条件的性质做出决定。如果你正在执行基于计数的循环,那么FOR循环将是最有意义的。

for( cur = 0; cur < myList.Length; cur++ ){
    doSomething( myList[cur] );
}

如果您正在执行基于逻辑的循环,那么WHILE将实现最干净的实现

Iterator i = myObject.getIterator();
while( i.hasNext() ){
    doSomething( i.next() );
}

答案 6 :(得分:7)

正如你所说,原因是语义和美学,而不是性能(它们的编译代码往往非常相似)。

也就是说,for通常具有已知迭代次数的循环,而while意味着该条件不一定与您在循环中所做的事情相关,或者你不知道一开始会有多少次迭代。

答案 7 :(得分:7)

通常,我总是喜欢循环,即使循环与计数无关的情况,因为它将循环的维护本地化在一个位置。当其他人出现并决定添加/修改循环时,如果他们使用FOR循环,那么进行修改的人通常可以确信,只要他们不会弄乱FOR表达式中的项目,他们不会在循环中打破迭代。

然而,像while循环这样的东西需要程序员完全解析循环体,并理解它如何迭代,以确保它们在进行更改时保持循环维护代码不变并且顺序正确。

因此,在我只有效地需要FOR的中间部分的情况下,我使用WHILE。

答案 8 :(得分:4)

它们在功能上是相同的,但是,可以认为for循环不易出错,因为所有的循环功能都在一起。如果你有几行分隔i的声明,while声明和索引迭代器,你可能会忘记,或者对它的使用方式感到困惑。当然这都是主观的。

答案 9 :(得分:3)

在编程的早期阶段,流行的数据结构是线性数组(又名矢量),重复模式是遍历并使用数组的每个元素。通常这种情况是语言包含此模式的特定语法:for循环。除了这个历史遗产,你可以使用while循环(现在很好用F#这样的函数式语言,你宁可使用List.map或List.fold; - )

答案 10 :(得分:3)

这主要是可读性问题。通常,当您具有要迭代的已定义值范围时,请使用for循环。在不进行迭代时使用while循环,或者不知道退出条件何时为真。

从java的角度来看,我发现for循环对于集合非常方便:

for (Object o : objects){
    o.process();
}

比阅读更容易:

int i=0;
while(i < objects.size()){
    objects.get(i).process();
    i++;
}

答案 11 :(得分:3)

他们通常会编译成相同的最终结果。我大多数时候都喜欢或者每次都喜欢。写作

for (;x<5;x++){ 
    //do work 
} 

并不是那么邪恶,而是写作

while(x<5){
    x++
    //do work
}

而不是

while(x<5){
    //do work
    x++
}

可能会让一些人感到困惑并造成一个错误。

答案 12 :(得分:3)

在像Pascal这样的语言中,for和while构造具有不同的应用程序。你可以在Pascal中编写一个for循环,如下所示:

for i := 1 to 5 do
begin
{ some code here }
end

因此,您明确声明i增加1.此处没有明确指定终止条件。因此,您可以仅在已知循环将在实际循环执行开始之前运行某些预定次数的位置使用for循环。另一方面,您可以在while循环的情况下指定显式终止条件。

i:=0;
while (i<>5) do
begin
{ some code here }
i:=i+1;
end

因此while循环更灵活。后来在开发C时,虽然支持for和while,但for结构的含义发生了变化,你可以使用布尔运算符添加显式终止条件。因此,在C和C类语言中while和for的功能是相同的,因此它比可用性问题更像是一个可读性问题。

答案 13 :(得分:2)

瞥了一眼其他(非常好的)答案,有一点我没有看到。 (如果它确实成功了,我就错过了并道歉。)

我将给你两个看似语义相同的代码片段。

Snippet#1:

for (int a = 0; a < arr.length; a++) {
  /* do some work here */
}

Snippet#2:

int b = 0;
while (b < arr.length) {
  // do work
  b++;
}

他们看起来像做同样的事情,对吧?现在让我为每个片段添加一行,让我们看看会发生什么:

代码段#3:

for (int c = 0; c < arr.length; c++) {
  /* do some work here */
}
printf("%d\n", c);

Snippet#4:

int d = 0;
while (d < arr.length) {
  // do work
  d++;
}
printf("%d\n", d);

因此,当我编译一个垃圾文件时嵌入了这四个片段(加上一些胶水使arr.length意味着什么)我得到以下错误:

$ clang junk.c
junk.c:20:17: error: use of undeclared identifier 'c'
        printf("%d\n", c);
                       ^
1 diagnostic generated.

事实证明,使用for循环可以为虚拟计数器变量等提供更多的局部性。这使您在重复使用变量名称时有更大的余地而不会发生碰撞(尽管代价是增加潜在的阴影)。

答案 14 :(得分:1)

只需决定一个,然后在整个项目中复制并粘贴/调整它。减少决策,减少打字,加快编码速度。性能差异微不足道。

此外,我不是Justin将i保留在循环范围内,我使用 循环外var aL = array.length。然后在i循环构造函数中使用aLfor,这样就不会重新计算每次匹配时数组的长度(以及反复创建的var;))。再次否定。性能真的(参见我的答案的第一点),除非你有很大的阵列飞来飞去。如果你碰巧知道前面的数组长度首先使用固定长度启动它(在糟糕的浏览器上分配内存有轻微帮助;)如果这是客户端并且你有大量数据)。

js例子

<script>
var i=0;
var myArray = ["D","R","Y"];//literal style will do for now;)
var aL=myArray.length; //or use 3 if known upfront
for(i;i<aL;i++){/*always do DRY things here*/}
</script>

还确保在满足条件时,问问自己“我还需要完成整个循环吗?”如果不是,不要忘记尽早摆脱循环。

答案 15 :(得分:1)

可读性是一个非常重要的观点,但它可以双向运作。我将for-loop转换为while循环 - 即使我正在使用计数器变量,否则它将“自然”使用 - 当它更具可读性时。当你在三个部分或多个计数器中有任何长表达式或复杂表达式时(这与复杂的相关),这很常见。

Knuth's loop-and-a-half在几种语言中也更好,作为一个带有中断的无限循环,而不是for循环。

然而,有一个非常重要的语义差异:

for (int i = 0; i < arr.length; i++) {
  if (filter(arr[i])) continue;
  use(arr[i]);
}

int i = 0;
while (i < arr.length) {
  if (filter(arr[i])) continue;
  use(arr[i]);
  i++;
}

答案 16 :(得分:1)

简单地说:

'for'循环倾向于用于迭代使用。您需要遍历数组,出于各种原因需要数字1到100(或其他范围)。

'while'循环往往是一个条件循环。你想继续做一些事情,直到一个假的错误。假设你有一个名为'Toast'的课程,你想要烤面包,直到它被烘烤,你会得到类似下面的东西:

while (!toast.isToasted) cook(toast);

你总是可以(我不能想到一个你不能做的例子)将for循环写成while循环,将while循环写为for循环,但是选择一个最好的情况通常来自低于我的上述观点。

答案 17 :(得分:1)

相关琐事:

在Google的新Go language中,他们决定不再包含 while 语句。相反,它们允许您编写仅具有条件子句的for statement。 <等等

while (a < b) { ... }

就是

for a < b { ... }

答案 18 :(得分:1)

forwhile循环之间存在语义差异。使用for循环时,迭代次数是预定义的,而使用while次循环则不是必需的。

某些语言(例如Ada)通过使for循环计数器在循环体内成为常量来强制执行此操作。因此,例如说:

是违法的
for i in values'range loop
   ...
   i := i + 1;   -- this is illegal, as i is a constant within the loop body
end if;

然而,对于大多数语言而言,这种语义差异并不那么明显,它们不会将for循环计数器视为常量。

答案 19 :(得分:1)

可读性。每当我看到我想哭的时候,从旧的VB 6天 wend

在某些情况下,循环很好用。在返回true / false的对象上调用函数,但在该对象内迭代一个值。

示例是C#中的DataReader:

List<string> strings = new List<string>();
while(DataReader.Read())
{
  strings.Add(DataReader["foo"].ToString());
}

for循环允许您将工作封装在一个函数中,从而提供更好的内存管理。此外,如果你的while循环中有错误,它可能会进入一个威胁所有生命的失控循环:

bool keepGoing = true;
while(keepgoing)
{
   try
   {
     //something here that causes exception, fails to set keepGoing = false;
     keepGoing = false;
   }
   catch(Exception)
   {
    //Do something, but forget to set keepGoing.
    //maybe there is always an exception...
   }

}

我也认为这只是一般做法。很像建筑。您可以使用钉子将屋顶平面放在螺柱上。你“可以”使用螺丝,他们会做同样的工作,但这不常见。

没有人说这是错的,我们只是说“请在同行的压力下弃牌以保持编码世界的正常运作”。

答案 20 :(得分:1)

通常,while循环和for循环之间的区别是语法而不是性能相关。也就是说,看起来这个问题已经解决了Java:Java for loop vs. while loop. Performance difference?

答案 21 :(得分:0)

For循环通常更容易并行化。由于程序可以预先告知将要执行的迭代次数和迭代器的值,因此使用诸如OpenMP之类的API进行并行化是微不足道的。当然,如果你进入休息状态,继续并手动更改迭代器,这种优势就会消失。

答案 22 :(得分:0)

在适当的时候使用for循环。 while解决方案有语法上的缺点(它更长),你必须检查你在循环中的任何继续调用之前增加i。

答案 23 :(得分:0)

因为后者可以是一个班轮:而(++ i&lt; arr.length){// do work}

答案 24 :(得分:0)

一个原因是,一段时间的条件可以是一个字符串。

另外,如果我们在混合中添加'Do',我们可以使用do while循环,当我们希望操作至少运行一次时,无论其当前状态如何。

答案 25 :(得分:0)

它只是我的逻辑,当我们知道我们的迭代的确切计数时我们通常使用for循环,当我们通常想要检查条件时我们使用while循环。然后我们根据你的要求使用它们。否则他们都表现出相同的行为。

答案 26 :(得分:0)

偏好。对我来说,所有循环逻辑都内置在for语句中,因此您不必声明计数器变量或在实际循环中执行递增/递减操作。此外,您可以声明for语句的本地计数器/索引。

答案 27 :(得分:0)

while循环,定义为

while(condition)

表示这种编程模式:

1:
if(!condition) goto 2;
...
goto 1;
2:

而for循环,定义为

for(var i = seed; condition; operation)

代表这种模式:

var i = seed
1:
if(!condition) goto 2;
...
operation;
goto 1;
2:

这两种模式都是如此常用,它们已经被命名并构建成语言。

如果您需要定义一个计数器来控制循环,请使用for循环。如果没有,请使用while循环。