Прерывание оператора if внутри цикла for - PullRequest
0 голосов
/ 26 марта 2019

Как завершить отображение цикла после выполнения, где галлоны <100 и часы <24. Я могу получить «Рыба умерла после ... часов», но не знаю, как остановить первый printf () в для цикла от выполнения. </p>

Я пытался использовать оператор break с отступом в операторе if, но это влияет только на цикл 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.

Ответы [ 2 ]

1 голос
/ 26 марта 2019

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).Лучше структурированное решение состоит в том, чтобы завершить цикл одним только ограничением цикла.В этом случае это можно сделать:и понять.

0 голосов
/ 27 марта 2019

У вас все еще есть небольшая проблема с определением вашего цикла управления.Вы также приглашаете Endless Loop , если во время ввода возникает ошибка соответствия , потому что вы не можете проверить возвращение scanf (вероятно, одна из самых больших ошибок, с которыми сталкиваются новые программисты C)).Попытайся.Введите "one gallon" в ответ на приглашение и посмотрите, что произойдет.Далее, после проверки возврата, вы должны обработать 3 случая:

scanf можно использовать, если используется правильно.Это означает, что вы несете ответственность за проверку возврата из scanf каждый раз .

  1. (return == EOF) пользователь отменил ввод, сгенерировав руководство EOF, нажав Ctrl + d (или в окнах Ctrl + z , но см. CTRL + Z не генерирует EOF в Windows 10 (более ранние версии) );
  2. (return < expected No. of conversions) a , соответствующий или , на входе произошла ошибка.Для сбоя match вы должны учитывать каждый символ, оставшийся в вашем входном буфере.(сканирование вперед во входном буфере с чтением и отбрасыванием символов, пока не будет найдено '\n' или EOF);и, наконец,
  3. (return == expected No. of conversions), указывающий на успешное чтение - тогда вам нужно проверить, соответствует ли входные данные каким-либо дополнительным критериям (например, положительное целое число, положительная плавающая точка, в необходимом диапазоне и т. д.).).

На вашу логику петли.Учитывая ваш пример и ваш вопрос «Разбить оператор if внутри цикла for », я думаю, я знаю, куда вы хотите пойти - и вы можете добраться туда одним из самых простых, наименее используемых и откровенно откровенных, обязательно, выражения для управления вложенным циклом.Хорошее оле goto утверждение.Он по-прежнему имеет место в программировании, и хотя он не должен использоваться чрезмерно, есть несколько обстоятельств, таких как те, что указаны выше, и на самом деле ваши обстоятельства, когда вполне нормально использовать 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 < n, и вы настраиваетевывод, как требуется выше. Хотя это не является обязательным, он очень условен, и в нем предусмотрены массивы с нулевым индексом в C, а также часы на часах, которые запускают 0 -> 23, а не1 - > 24. Название фильма «Нулевой темный тридцать» является хорошей аналогией (например, ноль часов тридцать минут или 12:30 am.) Вы не можете попасть туда зацикливанием 1 <= 24, поэтому эти ограничения не могут смоделировать концепциювремя правильно)

Обратите внимание на использование goto.Используется вместе с проверкой vol < 100.Если vol < 100 тестирует TRUE, то управление передается метке , связанной с оператором goto.(здесь обозначение deadfish:;).Это обеспечивает несколько преимуществ здесь.Ваша петля for может просто отслеживать время - количество часов, в течение которых бак протекает до 24.Обратите внимание, что падение громкости ниже 100 приводит к тому, что элемент управления перепрыгивает через выход живой рыбы, который выполняется при нормальном выходе из цикла.

Хотя вы можете получить желаемый выход мертвой рыбы, включив if (vol < 100) /* print dead fish */; break; else if ...становится очень трудно получить ваш метод /* print live fish */ при обычном выходе из цикла таким образом, без повторной проверки счетчика цикла как части предложения else if.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, зная, что его не следует использовать чрезмерно, но у него есть несколько применений, где он может обеспечить оптимальное решение, и в случае разрыва вложенного цикла это единственный инструмент в вашем наборе инструментов, которыймогу это сделать.

...