Почему этот цикл идет вечно? - PullRequest
1 голос
/ 30 апреля 2019
int main() {
        for(3;2;1)
            printf("hello\n")
}

Я думал, что этот цикл даже не будет выполнен. AFAIK мы должны определить переменную; поставить условие; увеличение уменьшение. Однако в этом коде ничего из того, что я насчитал, не существует. Поэтому я думаю, что эта программа должна потерпеть крах. Но это продолжается вечно.

Ответы [ 6 ]

4 голосов
/ 30 апреля 2019

Поскольку условие выхода (2) всегда истинно.

Это работает, потому что формат оператора for

for (clause-1;expression-2;expression-3)

Где clause-1 может быть объявлением (например, int i = 0) или выражением.

В вашем случае у вас есть три выражения, так что утверждение все еще синтаксически допустимо.

Цикл завершается, когда expression-2 оценивается как false (0), что, в вашем случае, никогда не происходит, поскольку это ненулевая константа (2).

3 голосов
/ 30 апреля 2019

Условное выражение остановки 2 никогда не равно нулю.

Так что цикл работает вечно.

2 голосов
/ 30 апреля 2019

AFAIK мы должны определить переменную; поставить условие; увеличение уменьшение. Однако в этом коде ничего из того, что я насчитал, не существует. Поэтому я думаю, что эта программа должна потерпеть крах. Но это продолжается вечно.

При изучении циклов for вы, вероятно, подвергались очень специфическому использованию цикла и, следовательно, экстраполировали его на то, что может или не может появиться там синтаксически. Но вы не получили полную картину. Существует стандарт для этого языка Си, и именно этот стандарт определяет, как цикл может быть написан и как он будет себя вести. Для цикла мы можем взглянуть на §6.8.5 (оператор итерации), чтобы определить правильное поведение:

  iteration-statement:
          while ( expression ) statement
          do statement while ( expression ) ;
          for ( expression<sub>opt</sub> ; expression<sub>opt</sub> ; expression<sub>opt</sub> ) statement
          for ( declaration expression<sub>opt</sub> ; expression<sub>opt</sub> ) statement

Это грамматика для всех циклов. Видите, как цикл for допускает произвольное выражение во всех 3 местах? Так как даже 1, 2 и 3 являются выражениями в C, они могут идти туда. И стандарт даже говорит нам, какое поведение должно быть:

Оператор итерации приводит к многократному выполнению оператора, называемого телом цикла, до тех пор, пока управляющее выражение не станет равным 0.

Заявление

for ( clause-1 ; expression-2 ; expression-3 ) statement

ведет себя следующим образом: выражение-выражение-2 является управляющим выражением, которое вычисляется перед каждым выполнением тела цикла.

Итак, 2 необходимо оценить и сравнить равным 0. Что никогда не произойдет, отсюда и поведение, которое вы наблюдали.

2 голосов
/ 30 апреля 2019

C - это не оболочка Борна, как в for i in 3 2 1 ; do echo hello ; done

Правильный цикл выглядит так:

#include <stdio.h>
int main() {
        for(int i = 1; i <=3 ; i++)
            printf("hello\n");
}

Здесь условное выражение i <= 3 не всегда верно, как 2. Истина - это любое ненулевое значение.

1 голос
/ 30 апреля 2019

A for цикл не требует использования каких-либо переменных.Он просто определяет использование трех выражений , каждое из которых может быть необязательным:

for ( <em>expression-1<sub>opt</sub></em> ; <em>expression-2<sub>opt</sub></em> ; <em>expression-3<sub>opt</sub></em> ) <em>statement</em>

Сначала оценивается выражение-1 (если оно присутствует),Это выражение обычно инициализирует условие, которое мы будем проверять в expression-2 , но не имеет to.

Далее, expression-2 оценивается.Если результат выражения не равен нулю, то тело цикла будет выполнено.Если expression-2 отсутствует, то оно неявно заменяется на 1.

После выполнения тела цикла вычисляется expression-3 .Это выражение обычно обновляет условие, которое мы проверяем в expression-2 , но, опять же, оно не имеет до.

Повторение двух последних шагов до expression-2 оценивается в ноль.

В случае for ( 1; 2; 3 ) ..., 2 оценивается в ненулевое значение, поэтому выполняется тело цикла.Поскольку это значение никогда не меняется, цикл выполняется «навсегда».Вы получаете тот же результат с for (;;).

1 голос
/ 30 апреля 2019

мы знаем 0 ложно и 1 верно.В этом случае в условном выражении for( ;2;) всегда верно, как while(2).поэтому он будет работать бесконечно..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...