【问题标题】:Loops in C - for() or while() - which is BEST?C 中的循环 - for() 或 while() - 哪个是最好的?
【发布时间】:2011-01-15 14:31:42
【问题描述】:

for() 或 while() - 哪个是最好的?

for (i=1; i<a; i++)
  /* do something */

i=1;
while (i<a) {
/* do something */
i++;
}

【问题讨论】:

  • 视情况而定。你有continue; 作为/* do something */ 的一部分吗?然后循环甚至不做同样的事情。
  • 在什么意义上最好?
  • 当然,这是主观问题的定义。
  • @pavium:不是这样;社区有标准的习惯用法和最佳实践。
  • @Jason,好吧,我可以看出这不是争论(也没有人投票关闭它)。

标签: c for-loop while-loop


【解决方案1】:

第一种是惯用的方式;这是大多数 C 程序员希望看到的。但是,我应该指出,大多数人也希望看到

for(i = 0; i < a; i++)

请注意,循环从零开始。这将做一些a 次。如果你要编写一个while 循环,它相当于上面的for 循环,我强烈建议你将它写成for 循环。同样,这是 C 编码人员希望看到的。此外,作为for 循环,它更易于阅读,因为所有内容(初始化、循环条件、每次迭代后要执行的表达式)都在一行上。对于while 循环,它们分散开来,妨碍了可读性。

但请注意,在某些情况下,看似等效的 forwhile 循环实际上并非如此。例如:

for(i = 0; i < 10; i++) {
    if(i == 5) continue;
    printf("%d\n", i);
}

i = 0;
while(i < 10) {
    if(i == 5) continue;
    printf("%d\n", i);
    i++;
}

乍一看似乎是等价的,但实际上并非如此。 for 循环将在控制台上打印0--9,跳过5,而while 循环将在控制台上打印0--4,然后进入无限循环。

现在,处理您询问的简单案例。你没有问过的更复杂的案例呢?嗯,这真的取决于,但一个好的经验法则是:如果你要重复某件事固定的预定次数,for 循环通常是最好的。否则,使用while 循环。这不是一成不变的规则,但它是一个很好的经验法则。例如,你可以写

unsigned int v;
unsigned int c;
for(c = 0; v; v >>= 1) c += v & 1;

但我认为大多数 C 程序员会这样写

unsigned int v;
unsigned int c;
c = 0;
while(v) { c += v & 1; v >>= 1; }

或者,作为另一个示例,如果您要读取到文件末尾,那么您应该使用while 循环。因此

FILE *fp;
fp = fopen(path, "r");
while(fgets(buf, max, fp) != NULL) { /* something */ }

而不是

FILE *fp;
for(fp = fopen(path, "r"); fgets(buf, max, fp) != NULL; ) { /* something */ }

现在,进入宗教领域,这就是为什么我更喜欢 while(1) 作为执行无限循环而不是 for(;;) 的正确方法。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    在这种情况下哪个最有意义。

    for 循环告诉您它很可能是一个固定计数循环。从 1 开始,在 a 之前结束。

    while 循环并不意味着任何这样的事情,只是它结束一次i &gt;= a(至少从阅读顶部的while (i&lt;a){ 开始)。

    当然,这不是一个规则,程序员通常会按照他们认为合适的方式进行操作,但它确实可以轻松阅读代码,而无需回溯以理解某些部分。

    【讨论】:

      【解决方案3】:

      这取决于。使阅读最容易的应该是恕我直言的指导方针。如果您事先知道界限,您可能应该使用“for”。因为它在一行中清楚地说明了循环的开始、结束以及如何从一个元素转到另一个元素。

      【讨论】:

        【解决方案4】:

        投票给 Dan McG - 如果循环具有固定计数等,请使用 for - 它更符合习惯用法。各经典案例:

        for (i = 0; i < THRESHOLD; ++i) {
          something;
        }
        

        对比

        while (foo->next) {
          foo = foo -> next; 
        }
        

        另外:如果您发现自己在 for 中遗漏了条件,请考虑一下如果您重新编写它会是什么样子。

        在一天结束时:返回并阅读循环的每个版本。在你的脑海中,哪一个在意图上更“清晰”?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-13
          • 2019-04-01
          • 2013-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-06-23
          • 2014-08-21
          相关资源
          最近更新 更多