【问题标题】:For versus while versus do loop statementsFor 与 while 与 do 循环语句
【发布时间】:2017-03-08 23:53:18
【问题描述】:

forwhile 语句之间有区别吗?只是语法吗?

#include <stdio.h>

void main() {
    int cent_temp = 0;
    int fah_temp;
    while (cent_temp <= 20) {
        fah_temp = (9 * cent_temp) / 5 + 32;
        printf("%d degrees C = %d degrees F\n", cent_temp, fah_temp);
        cent_temp++;
    }
}

这对我来说意味着......

cent_temp 的值小于20 时,计算fah_temp。然后将cent_temp 的值增加1 并检查它是否仍然小于20;然后再循环一次。

关于语法:

printf("%d degrees C = %d degrees F\n", cent_temp, fah_temp);

这表示%d 表示打印到屏幕,用十进制数替换cent_temp 的值,%d 表示用十进制数替换fah_temp 的值。

#include <stdio.h>

void main() {
    int cent_temp;
    int fah_temp;
    for (cent_temp = 0; cent_temp <= 20; cent_temp++) {
        fah_temp = (9 * cent_temp) / 5 + 32;
        printf("%2d degrees C = %2d degrees F\n", cent_temp, fah_temp);
    }
}

我对上面的解释是: 对于cent_temp = 0 重复而cent_temp 小于20 然后在最后执行cent_temp+1。所以cent_temp0 进入循环计算fah_temp 并打印到屏幕上。然后cent_temp 上升一个然后再次循环。在这里,我使用 %2d 而不是 %d 来表示它应该有 2 个空格来表示十进制数(并且在执行时它们会对齐)。如果cent_temp &gt; 20,这两个代码都不会执行。

do while 循环中类似地重新排列语句具有类似的效果,并且对结果没有真正的影响。

每种类型的循环都有不同的应用吗?

如有错误请指正!

【问题讨论】:

  • 你可能想看看一本好的 C 书。他们中的大多数详细说明了不同循环的作用,特别是for 语句的作用(这确实是语法糖)。他们还应该详细说明每个陈述更适合的地方。编写人类可读的代码。注意:do 循环确实不同!

标签: c


【解决方案1】:

'for' 和 'while' 语句之间有区别吗?难道只是 语法?

对我来说,这只是语法。

K&R 第 3.5 节循环 -- While 和 For,我引用:

for 声明

for (expr1; expr2; expr3)
  statement

等价于

expr1;
while (expr2) {
  statement
  expr3;
}

continue 的行为除外。

从语法上讲,for 循环的三个组成部分是表达式。 最常见的是,expr1expr3 是赋值或函数调用 而expr2 是一个关系表达式。

备注

正如用户 @chqrlie 在 cmets 中提到的那样,breakcontinue 之类的控制语句使情况变得更加模糊。

在某些情况下,循环体中需要修改语句。例如Erase-remove idiom with std::set failing with constness-related error(虽然在 C++ 中)

示例

例如,让我们编写一个循环来打印 1 到 100 之间的所有奇数。

int i = 1;
while (i <= 100) {
  printf("%d\n", i);
  i += 2;
}

for (int i = 1; i <= 100; i += 2) {
  printf("%d\n", i);
}

意见

我不是语言专家,但在实践中的大多数情况下,我发现它们是可以转换的。

我个人更喜欢使用for 语法,因为:

  • 循环控制结构在一个地方(for 标头)使其易于阅读,并且
  • 循环变量(例如i)未暴露于外部范围。

【讨论】:

  • 这过于简单化了。 :)
  • @SouravGhosh 你能举个反例吗?
  • @unwind 你期待哪种反例?
  • @Arun 所说的不正确的情况。我认为没有,我相信上述转换一直有效。
  • @unwind:如果在循环体中有 continue 语句,因为 modify something 部分仍将在 @987654337 中执行,这是一种过度简化@ 声明,将在建议的while 翻译中被跳过。
【解决方案2】:
for(cent_temp = 0; cent_temp <= 20; cent_temp++)
{ /* code */ }

100% 等价于

cent_temp = 0;
while(cent_temp <= 20)
{
  /* code */
  cent_temp++;
}

do-while 不同,因为它将条件检查放在最后。


至于何时使用哪个循环,这是风格问题,因此有点主观。大多数 C 程序员使用的行业事实上的标准风格是这样的:

  • for 在执行已知次数的迭代时应始终使用循环。然后它被认为是最易读的形式。
  • while 循环应该用于迭代次数事先未知,或者当循环由于某种原因变得复杂时。例如,如果您需要更改循环体内的循环迭代器变量,那么您应该使用while 循环而不是for 循环。
  • do while 循环应该用于需要在循环的第一圈跳过条件检查的特殊情况,例如 do { result = send(); } while(result == ok);

【讨论】:

  • 我宁愿扩展for的用法:如果三个部分(初始化、条件和进入下一步)密切相关,则最好。不过,所有这些都不是硬性标准。最重要的是可读性。 do ... while 是完全不同的野兽,因为它有不同的行为。没有对应的do ... for
  • @Olaf 是的,我同意。有一个很好的经验法则,for 循环的 3 个表达式应该只关注循环迭代器,而不是其他不相关的东西(这也是 MISRA-C 规则)。
  • 适合初学者的良好方向(MISRA 值得阅读规则的基本原理,但忘记规则本身)。这就像烹饪:一个好的厨师和一个好的程序员知道什么时候可以稍微改变一下规则。如果你失败了,两者都会导致糟糕的产品:-)
【解决方案3】:

从算法的角度来看 for 和 while 是不一样的。简而言之,在算法中,当边界已知并且您不知道条件是否可以满足或何时可以满足时,应该使用 for。 For 是重复某件事 n 次(n 已知),这正是您的示例计算的情况;应该使用 for 循环(你不认为循环的作用在 for 循环中更清楚地说明了吗?)。如果您想要一个必须使用的 while 循环的示例,请查看 Collat​​z 序列之类的内容。从可计算性的角度来看,for 循环总是可以转换为 while 循环,但不能反过来。

从计算机语言的角度来看,融合两者现在很常见,例如在 C 中,它没有区别,只有句法。但请记住,在其他一些可能非常不同的语言中,例如在 Pascal 中,for 循环非常有限。

【讨论】:

    【解决方案4】:

    我查看了我的 Code Complete 由 Steve McConnell(圣经)

    这是您在第 16 章中可以阅读的内容:

    当您需要一个执行指定次数的循环时,for 循环是一个不错的选择。 [...]

    将 for 循环用于不需要内部循环控制的简单活动。当循环涉及简单的递增或递减时使用它们,例如遍历容器中的元素。 for 循环的要点是您将它设置在循环的顶部,然后忘记它。您不必在循环内做任何事情来控制它。如果您有执行必须跳出循环的条件,请改用 while 循环。

    同样,不要显式更改 for 循环的索引值来强制它终止。请改用 while 循环。 for 循环用于简单用途。大多数复杂的循环任务最好由 while 循环来处理。

    【讨论】:

      【解决方案5】:

      一般来说,您会使用for 循环来迭代一组有限的值,而您会使用whiledo-while 循环在特定条件或一组条件为真时进行迭代。在 C 的大多数同时代(Basic、Pascal、Fortran 等)中,for 循环只能迭代标量索引:

      Fortran:

            DO 10 i=1,10
              statements
         10 CONTINUE
      

      帕斯卡:

      for i := 1 to 10 do
      begin
        statements
      end;
      

      这两个 sn-ps 循环正好 10 次。索引i 由循环自动初始化和更新。我得回去检查一下,但我很确定你不能在循环体中写信给i

      C 通过添加控制表达式实际上模糊了forwhile 循环之间的界限:

      for ( init-expr ; control-expr ; update-expr )
        statement
      

      在 C 中,for 循环可以像 Fortran 或 Pascal 一样迭代标量:

      for( i = 0; i < 10; i++ )
      {
        do_something_with( i );
      }
      

      或者它可以迭代多个标量:

      for ( i = 0, j = 0; i < 10 && j < 10; i++, j++ )
      {
        do_something_with( i, j );
      }
      

      或者它可以遍历文件的内容:

      for( c = fgetc( in ); c != EOF; c = fgetc( in ) )
      {
        do_something_with( c );
      }
      

      或者它可以遍历一个链表:

      for( cur = head; cur != NULL; cur = cur->next )
      {
        do_something_with( cur );
      }
      

      在 Fortran 和 Pascal 中,最后三个循环必须表示为 while 循环(我不会这样做,因为我已经用尽了我的 Fortran 和 Pascal 知识)。

      C for 循环与 Fortran 或 Pascal 循环之间的另一个大区别是您可以在循环中写入循环索引(ijccur)身体;它没有受到任何特殊保护。

      只要特定条件或一组条件为真,就会使用 whiledo-while 循环进行迭代:

      while( control-expr )
        statement
      
      do
        statement
      while( control-expr );
      

      forwhile 循环中,条件在循环体执行之前进行测试;在do-while 循环中,条件在循环体执行后进行测试,因此do-while 循环将始终至少执行一次。

      在 C 中,您可以在许多情况下使用 for 循环或 while 循环:

      while ( ( c = fgetc( in ) ) != EOF )
        do_something_with( c );
      
      for ( c = fgetc( in ); c != EOF; c = fgetc( in ) )
        do_something_with( c );
      

      两个循环的作用完全相同;只是你认为哪个更清楚地表达了你的意图,或者你认为哪个更容易被其他人理解的问题。

      【讨论】:

        【解决方案6】:

        编写源代码不仅是为了让计算机编译和执行,而且是为了让人类阅读和理解。

        计算机并不真正介意使用for 循环、while 循环还是goto。另一方面,人类对不同的结构有不同的期望。

        • 在已知输入范围内计算值最好使用for 循环显示;
        • 最好使用while 循环来将文件读到底。​​li>

        选择要使用的结构类似于选择变量名。

        【讨论】:

          猜你喜欢
          • 2020-05-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-20
          • 2013-08-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多