5

好像

while( condition ) {
    //do stuff
}

完全等价于

for( ; condition; ) {
    //do stuff
}

有什么理由使用后者而不是前者?

4

17 回答 17

23

据我所知,没有充分的理由。您通过使用不会增加任何内容的 for 循环来故意误导人们。

更新:

根据 OP 对该问题的评论,我可以推测您如何在实际代码中看到这样的构造。我以前见过(并使用过)这个:

lots::of::namespaces::container::iterator iter = foo.begin();
for (; iter != foo.end(); ++iter)
{
    // do stuff
}

但这就是我将事情排除在for循环之外的情况。也许您的项目曾经有一个看起来像这样的循环。如果您在循环中间添加删除容器元素的代码,您可能必须仔细控制如何iter递增。这可能会导致代码如下所示:

for (; iter != foo.end(); )
{
    // do stuff

    if (condition)
    {
        iter = foo.erase(iter);
    }
    else
    {
        ++iter;
    }
}

但是,这不是不花五秒钟时间将其更改为 while 循环的借口。

于 2009-09-04T13:28:50.887 回答
8

一些编译器警告常量循环条件:

while (true) { /* ... */ } /* Warning! */
for (;;) { /* ... */ } /* No warning */

在无限循环的特定情况下,出于这个原因,我可能会选择 for 循环而不是 while 循环。但如果条件不为空,我真的看不到任何好处。我对为什么它出现在上述项目中的猜测是代码以某种方式通过维护而演变,但最初是以更传统的方式编写的。

于 2009-09-04T15:07:11.157 回答
8

有什么理由使用后者而不是前者?

  1. 误导你的同事,让你知道这两种形式是等价的。
  2. 通过使您的代码尽可能混乱以确保没有人愿意更改它来确保“工作安全”是一种愚蠢的做法。
  3. 键盘上的“w”键坏了。
  4. 它最初是一个带有初始化器和递增条件的 for 循环,当逻辑发生变化时,开发人员忙于更改它。
于 2009-09-04T16:22:19.167 回答
7

不不不。

即使存在细微的性能差异,您也必须是末段的绝地性能调音师才能让它足够重要。

于 2009-09-04T13:37:09.007 回答
5

可以编译

for(INIT; CONDITION; UPDATE)
{
  BODY
}

进入

{
  INIT
  while(CONDITION)
  {
    BODY
    UPDATE
  }
}

更新:看似多余的额外范围是将任何变量定义笼罩在 INIT 中,即来自for(int i = 0; ...). 谢谢!

它基本上只是表达式的重新排序。因此,出于性能原因,没有理由更喜欢其中一个。如果可能的话,我会推荐while(),因为它更简单。如果一个更简单的结构表达了您想要做的事情,我认为这是可以使用的。

于 2009-09-04T13:33:16.577 回答
4

据我所知,编译器将这两个语句优化为相同的汇编代码。所以不,没有理由这样做 - 只是个人喜好。

于 2009-09-04T13:29:47.767 回答
3

我认为“while”和“for”循环适用于不同的习语。使用“while”的成语是“做某事,而某些条件为真”。“for”的成语是“迭代一定范围的元素”......

每当我阅读代码时,我都会期待这些习语(而且我认为我并不孤单)。当我看到“for”时,我明白有人正在迭代某个范围,我不会详细说明。当我看到用于另一个习语的 for 循环(不是我期望的那个)时,我感到困惑,不得不详细说明。

无论如何,这是非常主观的......

于 2009-09-04T14:53:07.997 回答
2

在这种情况下,我个人更喜欢第一个循环,因为它更容易编写和阅读。

但是如果我有一个需要一些 post 语句的循环,我会像这样使用 for 循环:

for (; i < 10; i += 2)
于 2009-09-04T13:30:06.110 回答
2

在汇编级别上可能存在与编译器相关的微小差异,但理想情况下两者的行为应该完全相同,并且前者更具可读性。所以不,除了不墨守成规之外,没有理由使用后一个版本。

于 2009-09-04T13:30:52.460 回答
2

编译两者并检查生成的反汇编,如果它们相同(它们可能是)。选择你认为最易读的一个。

于 2009-09-04T13:31:55.423 回答
1

如果您想在有限的时间内做某事,那么“for”让您指定约束,而不会将其与循环内的逻辑混为一谈。

于 2009-09-04T13:29:41.510 回答
1

暂时不考虑可读性,不同循环之间通常没有性能差异。至少没有显着差异。

对于桌面应用程序,您可以根据可读性标准进行选择。请参阅其他帖子 - 例如,查看 for 循环有人认为增量器是在循环中声明的。

对于 Web 应用程序,例如客户端脚本,似乎存在差异。

检查这个网站:http ://www.websiteoptimization.com/speed/10/10-2.html

运行您自己的实验并按照结果进行,否则请遵守可读性规则。

于 2009-09-04T13:32:16.750 回答
1

我可以看到两个原因,我都不会考虑:

  • 只有 1 个循环结构,但克里斯托的反对意见成立
  • 写“for (; EVER;)”,但如果真的想要这个,那么更喜欢 LOOP_FOREVER 宏。
于 2009-09-04T13:35:31.020 回答
1

在 for (;cond;) 循环和 while 循环之间,C-ish 语言确实没有区别。一般来说,我在 C-ish 语言中所做的就是开始将循环编写为“for”,如果我以这种形式结束,则将其更改为“while”。不过这有点少见,因为您总是在迭代某些东西,而 C 允许您在最后一个区域放置您想要的任何代码。

如果 C 有真实的(预先计算的迭代)for 循环,情况会有所不同。

于 2009-09-04T14:09:28.700 回答
1

您可能希望使用 do-while 循环而不是 for 循环,以便在检查和满足(或不满足)条件之前至少处理一次代码。

于 2009-09-04T15:34:06.747 回答
1

我曾经写过一些非常神秘的 C/C++ 代码。回想起来,我可能会在 while 循环中执行此操作:

ifstream f("file.txt");
char c;
for(f.get(c); !f.eof(); f.get(c)) {
  // ...
}

我想我的观点是 for 循环通常更短但可读性更低,如果它们不是在传统意义上的循环范围内使用的话。

于 2009-09-04T17:19:26.230 回答
1

这个问题已经得到解答——语言有一个更自然的结构来表达你想要的——你应该使用它。例如,我当然可以这样写:

for (bool b = condition(); b; b = !b) {
    /* more code */
}

或者:

while (condition()) {
    /* more code */
    break;
}

而不是更传统的:

if (condition()) {
    /* more code */
}

但为什么?C(和所有语言)都有习语,其中大多数在表达性和意义期望方面具有合理的意义。当您使用成语时,您会弄乱必须阅读您的代码的人的感受。

于 2009-09-04T18:16:31.497 回答