Казалось бы, бесконечный цикл заканчивается, если только система.из.используется метод println является


у меня был простой кусок кода, который был должно чтобы быть бесконечным циклом, так как x всегда будет расти и всегда будет оставаться больше, чем j.

int x = 5;
int y = 9;
for (int j = 0; j < x; j++) {
   x = x + y;
}
System.out.println(y);

но как есть, он печатает y и не петля бесконечно. Я не могу понять, почему. Однако, когда я изменить код следующим образом:

int x = 5;
int y = 9;
for (int j = 0; j < x; j++) {
    x = x + y;
    System.out.println(y);
}
System.out.println(y);

это становится бесконечным циклом, и я понятия не имею, почему. Распознает ли java его бесконечный цикл и пропускает его в первом ситуация, но должен выполнить вызов метода во втором, чтобы он вел себя так, как ожидалось? Растерялся:)

6 84

6 ответов:

оба примера не бесконечны.

проблема заключается в ограничении int введите Java (или почти любой другой общий язык). Когда значение x достигает 0x7fffffff, добавление любого положительного значения приведет к переполнению и x становится отрицательным, поэтому ниже, чем j.

разница между первым и вторым циклом заключается в том, что внутренний код занимает гораздо больше времени, и это займет, вероятно, несколько минут, пока x переполнений. Для первого примера это может занять меньше, чем второй и, скорее всего, код будет удален оптимизатором, поскольку он не имеет никакого эффекта.

как уже упоминалось в обсуждении, время будет сильно зависеть от того, как ОС буферизует вывод, выводит ли он в эмулятор терминала и т. д., поэтому он может быть гораздо выше, чем несколько минут.

поскольку они объявлены как int, как только он достигнет максимального значения, цикл сломается, поскольку значение x станет отрицательным.

но когда система.из.println добавляется в цикл, скорость выполнения становится видимой (так как вывод на консоль замедляет скорость выполнения). Однако, если вы позволите второй программе (с syso внутри цикла) работать достаточно долго, она должна иметь то же поведение, что и первая (без syso внутри цикла).

для этого могут быть две причины:

  1. Java оптимизирует for цикл и так как нет никакого использования x после цикла, просто убирает петлю. Вы можете проверить это, поставив System.out.println(x); оператор после цикла.

  2. возможно, что Java на самом деле не оптимизировать цикл и он выполняет программу правильно и в конечном итоге x вырастет слишком большой для int и переполнения. Целочисленное переполнение будет больше всего вероятно, сделать целое число x как отрицательный, который будет меньше j, и поэтому он выйдет из цикла и выведет значение y. Это также можно проверить, добавив System.out.println(x); после цикла.

кроме того, даже в первом случае в конечном итоге произойдет переполнение, что приведет ко второму случаю, поэтому он никогда не будет истинным бесконечным циклом.

Они оба не бесконечный цикл, изначально j = 0 , то, как долго, как J

Если вы не ищем пример бесконечного цикла, это должно выглядеть так

int x = 6;

for (int i = 0; x < 10; i++) {
System.out.println("Still Looping");
}

потому что (X) никогда не достигнет значения 10;

вы также можете создать бесконечный цикл с двойным циклом for:

int i ;

  for (i = 0; i <= 10; i++) {
      for (i = 0; i <= 5; i++){
         System.out.println("Repeat");   
      }
 }

этот цикл бесконечен, потому что первый цикл for говорит i

это конечный цикл, потому что когда-то значение x превышает 2,147,483,647 (что является максимальным значением int),x станет отрицательным и не более j больше, печатаете ли вы y или нет.

вы можете просто изменить значение y до 100000 и печать y в петле и петля сломается очень скоро.

причина, по которой вы чувствуете, что он стал бесконечным, заключается в том, что System.out.println(y); сделал код, который будет выполняться намного медленнее, чем без каких-либо действий.

интересная проблема на самом деле в обоих случаях цикл не бесконечен

но главное различие между ними заключается в том, когда он закончится и сколько времени x возьмет, чтобы превысить Макс int стоимость которого составляет 2,147,483,647 после этого она достигнет состояния переполнения, и цикл завершится.

лучший способ понять эту проблему, необходимо проверить простой пример и сохранить его результаты.

пример:

for(int i = 10; i > 0; i++) {}
System.out.println("finished!");

выход:

finished!
BUILD SUCCESSFUL (total time: 0 seconds)

после тестирования этого бесконечного цикла потребуется менее 1 секунды для завершения.

for(int i = 10; i > 0; i++) {
    System.out.println("infinite: " + i);
}
System.out.println("finished!");

выход:

infinite: 314572809
infinite: 314572810
infinite: 314572811
.
.
.
infinite: 2147483644
infinite: 2147483645
infinite: 2147483646
infinite: 2147483647
finished!
BUILD SUCCESSFUL (total time: 486 minutes 25 seconds)

в этом тестовом случае вы заметите огромную разницу во времени, затраченном на завершение и завершение работы программы.

если вы не терпение вы будете думать, что этот цикл бесконечен и не прекращается, но на самом деле это потребуется несколько часов, чтобы завершить и достичь состояния переполнения в i значение.

наконец, мы пришли к выводу, что после того, как мы поместили оператор print внутри цикла for, это займет гораздо больше времени, чем цикл в первом случае без оператора print.

это время, необходимое для запуска программы, зависит от характеристик вашего компьютера, в частности вычислительной мощности(мощности процессора), операционной системы и вашей среды IDE, которая компилирует программу.

я проверяю этот случай на:

Lenovo 2.7 GHz Intel Core i5

ОС: Windows 8.1 64x

IDE: NetBeans 8.2

для завершения программы требуется около 8 часов (486 минут).

также вы можете заметить, что шаг инкремента в цикле for i = i + 1 очень медленный фактор для достижения максимального значения int.

мы можем изменить этот фактор и сделать инкремент шага более быстрым для того чтобы испытать для петли в меньше времени.

если мы ставим i = i * 10 и проверить это:

for(int i = 10; i > 0; i*=10) {
           System.out.println("infinite: " + i);
}
     System.out.println("finished!");

выход:

infinite: 100000
infinite: 1000000
infinite: 10000000
infinite: 100000000
infinite: 1000000000
infinite: 1410065408
infinite: 1215752192
finished!
BUILD SUCCESSFUL (total time: 0 seconds)

как вы видите, это очень быстро по сравнению с предыдущим циклом

для завершения и завершения работы программы требуется менее 1 секунды.

после этого тестового примера я думаю, что он должен прояснить проблему и доказать обоснованность Збынек Высковский-ответ квр000, также это будет ответ на это вопрос.