Казалось бы, бесконечный цикл заканчивается, если только система.из.используется метод 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 ответов:
оба примера не бесконечны.
проблема заключается в ограничении
int
введите Java (или почти любой другой общий язык). Когда значениеx
достигает0x7fffffff
, добавление любого положительного значения приведет к переполнению иx
становится отрицательным, поэтому ниже, чемj
.разница между первым и вторым циклом заключается в том, что внутренний код занимает гораздо больше времени, и это займет, вероятно, несколько минут, пока
x
переполнений. Для первого примера это может занять меньше, чем второй и, скорее всего, код будет удален оптимизатором, поскольку он не имеет никакого эффекта.как уже упоминалось в обсуждении, время будет сильно зависеть от того, как ОС буферизует вывод, выводит ли он в эмулятор терминала и т. д., поэтому он может быть гораздо выше, чем несколько минут.
поскольку они объявлены как int, как только он достигнет максимального значения, цикл сломается, поскольку значение x станет отрицательным.
но когда система.из.println добавляется в цикл, скорость выполнения становится видимой (так как вывод на консоль замедляет скорость выполнения). Однако, если вы позволите второй программе (с syso внутри цикла) работать достаточно долго, она должна иметь то же поведение, что и первая (без syso внутри цикла).
для этого могут быть две причины:
Java оптимизирует
for
цикл и так как нет никакого использованияx
после цикла, просто убирает петлю. Вы можете проверить это, поставивSystem.out.println(x);
оператор после цикла.возможно, что 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, также это будет ответ на это вопрос.