【问题标题】:Breaking an if statement inside a for-loop在 for 循环中中断 if 语句
【发布时间】:2019-03-26 20:18:35
【问题描述】:

如何在加仑

我尝试过在 if 语句中使用缩进的 break 语句,但这只会影响 for 循环。

#include <stdio.h>

int main()
{
    double add, vol = 500;
    int hour;

    printf("Please enter additional water added per hour: ");
    scanf("%lf", &add);

    for (hour = 1; hour <= 24; hour++)
    {

        vol = (vol * 0.90) + add;

        printf("The volume is %.2f gallons after %d hours.\n", vol, hour);

        if (hour <= 23 && vol < 100)
            printf("The fish died after %d hours.", hour);


        else if (hour == 24 && vol >= 100)
            printf("Alas, The fish who lived.");
    }

    return 0;
}

预期结果:

Please enter additional water added per hour: 6
The volume is 456.00 gallons after 1 hours.
The volume is 416.40 gallons after 2 hours.
The volume is 380.76 gallons after 3 hours.
...
The volume is 103.33 gallons after 22 hours.
The volume is 99.00 gallons after 23 hours.
The fish died after 23 hours.

实际结果:

Please enter additional water added per hour: 6
The volume is 456.00 gallons after 1 hours.
The volume is 416.40 gallons after 2 hours.
The volume is 380.76 gallons after 3 hours.
...
The volume is 103.33 gallons after 22 hours.
The volume is 99.00 gallons after 23 hours.
The fish died after 23 hours. The volume is 95.10 gallons after 24 hours.

【问题讨论】:

  • but that only affects the for loop - 实际上,它还会影响什么?
  • .. 但这只会影响 for 循环 - 它会影响什么?
  • .. 在 if 语句中缩进.. - 也许您希望将 if 块包含在 {} 中?
  • "我尝试过在 if 语句中使用缩进的 break 语句" :您应该包含该尝试,而不是用文字描述它。您的意思并不完全清楚。
  • if (hour &lt;= 23 &amp;&amp; vol &lt; 100) 可以简单地为if (vol &lt; 100)hourelse if 中进行测试,&lt;= 23 与此条件检查无关。

标签: c for-loop break


【解决方案1】:

C 不是 Python,缩进在语法上并不重要。复合语句必须包含在{..}中:

    if (hour <= 23 && vol < 100)
    {
        printf("The fish died after %d hours.", hour);
        break ;
    }
    else if (hour == 24 && vol >= 100)
    {
        printf("Alas, The fish who lived.");
    }

我建议您始终{..} 用于条件或循环块,即使是单个语句。它使维护更简单。

但是,break; 可以说是一种相当不雅且结构不佳的退出循环的方式(与 continue 一样)。更好的结构化解决方案是仅通过循环约束来终止循环。在这种情况下,可以通过以下方式完成:

for( hour = 1; 
     vol > 100 && hour <= 24; 
     hour++)

有额外测试的开销,但在比这更复杂的代码中,可能有多个breaks,它可能变得难以维护、调试和理解。

【讨论】:

    【解决方案2】:

    您在搞清楚循环控制方面仍有一些问题。如果在输入过程中发生匹配失败,您也会邀请一个无限循环,因为您没有检查scanf 的返回(可能是新C 程序员最大的陷阱之一)掉进)。试试看。在提示输入时输入"one gallon",看看会发生什么。此外,检查退货后,您必须处理3种情况:

    scanf 可以使用,如果使用正确的话。这意味着有责任检查scanf返回每次

    1. (return == EOF) 用户通过按 Ctrl+d(或在 Windows Ctrl+z 上,但参见 CTRL+Z does not generate EOF in Windows 10 (early versions))生成手动 EOF 来取消输入;李>
    2. (return &lt; expected No. of conversions) 发生匹配输入 失败。对于 匹配 失败,您必须考虑输入缓冲区中剩余的每个字符。 (在输入缓冲区中向前扫描读取并丢弃字符,直到找到'\n'EOF);最后
    3. (return == expected No. of conversions) 表示读取成功 - 然后由您来检查输入是否满足任何其他条件(例如正整数、正浮点、在所需范围内等)。

    进入你的循环逻辑。鉴于您的示例和您的问题“在 for 循环中打破 if 语句”,我想我知道您想去哪里——您可以使用最简单、最少使用和坦率地说,嵌套循环控制的强制表达式。好的 olegoto 声明。它在编程中仍然占有一席之地,虽然不应该过度使用,但有几种情况,例如上面的情况,实际上你的情况,使用goto跳出循环是可以的并将控制权向下传递几行。 (限制是longjmp——你不想用它跳出函数)

    例如,如果我了解您在鱼类生存中的目标,您可以清理您的逻辑并合并scanf 验证,方法是将类似于以下内容的部分组合在一起:

     #include <stdio.h>
    
    int main (void) {
    
        double add, vol = 500;
        int hour;
    
        for (;;) {  /* loop continually until valid input is received */
            int rtn;    /* varible for scanf return - EVERY TIME  */
            /* there is no conversion taking place, fputs will do */
            fputs ("Please enter additional water added per hour: ", stdout);
            if ((rtn = scanf ("%lf", &add)) == EOF) {  /* handle EOF case */
                fputs ("(user canceled input)\n", stderr);
                return 1;
            }
            else if (rtn == 0) {    /* handle matching failure */
                fputs ("error: invalid double input.\n", stderr);
                /* empty all characters from stdin before next input */
                for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
            }
            else    /* handle good input */
                break;
        }
    
        for (hour = 0; hour < 24; hour++) {   /* loop 0 < 24 */
            vol = (vol * 0.90) + add;         /* adjust output hour + 1 below */
            printf ("The volume is %.2f gallons after %d hours.\n", vol, hour+1);
    
            if (vol < 100) {    /* don't forget the '\n' */
                printf ("The fish died after %d hours.\n", hour + 1);
                goto deadfish;  /* jump to deadfish label */
            }
        }
        puts ("Alas, The fish who lived.");     /* again, no conversion */
    
      deadfish:;   /* good ole goto label */
    
        return 0;
    }
    

    (注意: 通常循环在 C 中将运行 0 &lt; n 并且您根据上面的要求调整输出。虽然这不是强制性的,但它非常符合惯例,并且可以容纳 C 中的零索引,以及时钟上运行的小时数 0 -&gt; 23,而不是 1 - &gt; 24。电影“零黑暗三十”的标题是一个很好的类比(例如零小时三十分钟或12:30 am。)循环1 &lt;= 24 无法到达那里,因此这些限制无法正确模拟时间概念)

    注意上面使用goto。它与vol &lt; 100 检查结合使用。如果vol &lt; 100 测试TRUE,则控制权将传递给与goto 语句关联的标签。 (这里的标签是deadfish:;)。这在这里提供了几个好处。您的for 循环可以简单地跟踪时间——油箱泄漏到24 的时间。请注意低于100 的音量如何导致控制跳过将在正常循环退出时执行的活鱼输出。

    虽然您可以通过合并if (vol &lt; 100) /* print dead fish */; break; else if ... 获得所需的死鱼输出,但如果不再次检查循环计数器作为@987654353 的一部分,则很难在正常循环退出时获得/* print live fish */ 方法@ 子句。 goto 为这个问题提供了一个优雅的解决方案,它允许您在音量低于限制时传递对 /* print live fish */ 情况的控制,同时保留正常的循环退出,而无需测试您的循环计数器变量在循环本身内第二次。

    使用/输出示例

    确保您的程序可以为每个用户输入处理键盘上的猫踩踏。您必须每次都验证,例如

    $ ./bin/deadfish
    Please enter additional water added per hour: one gallon
    error: invalid double input.
    Please enter additional water added per hour: 1
    The volume is 451.00 gallons after 1 hours.
    The volume is 406.90 gallons after 2 hours.
    The volume is 367.21 gallons after 3 hours.
    The volume is 331.49 gallons after 4 hours.
    The volume is 299.34 gallons after 5 hours.
    The volume is 270.41 gallons after 6 hours.
    The volume is 244.37 gallons after 7 hours.
    The volume is 220.93 gallons after 8 hours.
    The volume is 199.84 gallons after 9 hours.
    The volume is 180.85 gallons after 10 hours.
    The volume is 163.77 gallons after 11 hours.
    The volume is 148.39 gallons after 12 hours.
    The volume is 134.55 gallons after 13 hours.
    The volume is 122.10 gallons after 14 hours.
    The volume is 110.89 gallons after 15 hours.
    The volume is 100.80 gallons after 16 hours.
    The volume is 91.72 gallons after 17 hours.
    The fish died after 17 hours.
    

    (键盘上的猫测试通过...)

    最接近 100 加仑的死鱼:

    $ ./bin/deadfish
    Please enter additional water added per hour: 6.53
    The volume is 456.53 gallons after 1 hours.
    The volume is 417.41 gallons after 2 hours.
    The volume is 382.20 gallons after 3 hours.
    The volume is 350.51 gallons after 4 hours.
    The volume is 321.99 gallons after 5 hours.
    The volume is 296.32 gallons after 6 hours.
    The volume is 273.22 gallons after 7 hours.
    The volume is 252.42 gallons after 8 hours.
    The volume is 233.71 gallons after 9 hours.
    The volume is 216.87 gallons after 10 hours.
    The volume is 201.71 gallons after 11 hours.
    The volume is 188.07 gallons after 12 hours.
    The volume is 175.79 gallons after 13 hours.
    The volume is 164.75 gallons after 14 hours.
    The volume is 154.80 gallons after 15 hours.
    The volume is 145.85 gallons after 16 hours.
    The volume is 137.80 gallons after 17 hours.
    The volume is 130.55 gallons after 18 hours.
    The volume is 124.02 gallons after 19 hours.
    The volume is 118.15 gallons after 20 hours.
    The volume is 112.86 gallons after 21 hours.
    The volume is 108.11 gallons after 22 hours.
    The volume is 103.83 gallons after 23 hours.
    The volume is 99.97 gallons after 24 hours.
    The fish died after 24 hours.
    

    (3 - 100 加仑死亡)

    第一条活鱼:

    $ ./bin/deadfish
    Please enter additional water added per hour: 6.54
    The volume is 456.54 gallons after 1 hours.
    The volume is 417.43 gallons after 2 hours.
    The volume is 382.22 gallons after 3 hours.
    The volume is 350.54 gallons after 4 hours.
    The volume is 322.03 gallons after 5 hours.
    The volume is 296.36 gallons after 6 hours.
    The volume is 273.27 gallons after 7 hours.
    The volume is 252.48 gallons after 8 hours.
    The volume is 233.77 gallons after 9 hours.
    The volume is 216.94 gallons after 10 hours.
    The volume is 201.78 gallons after 11 hours.
    The volume is 188.14 gallons after 12 hours.
    The volume is 175.87 gallons after 13 hours.
    The volume is 164.82 gallons after 14 hours.
    The volume is 154.88 gallons after 15 hours.
    The volume is 145.93 gallons after 16 hours.
    The volume is 137.88 gallons after 17 hours.
    The volume is 130.63 gallons after 18 hours.
    The volume is 124.11 gallons after 19 hours.
    The volume is 118.24 gallons after 20 hours.
    The volume is 112.95 gallons after 21 hours.
    The volume is 108.20 gallons after 22 hours.
    The volume is 103.92 gallons after 23 hours.
    The volume is 100.07 gallons after 24 hours.
    Alas, The fish who lived.
    

    (节省 7 - 100 加仑 - 如果需要,我会留给您进一步平分 1000 加仑)

    查看一下,如果您还有其他问题,请告诉我。将goto 放入您的 C 工具箱,知道它不应该被过度使用,但它有一些用途可以提供最佳解决方案,并且在打破嵌套循环的情况下,它是您工具箱中唯一的工具可以的。

    【讨论】:

      猜你喜欢
      • 2017-04-25
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 2016-06-16
      • 2019-06-09
      相关资源
      最近更新 更多