Ciekawy problem Właściwie w obu przypadkach pętla nie jest nieskończona
Ale główna różnica między nimi polega na tym, kiedy zakończy się i ile czasu x
zajmie przekroczenie maksymalnej int
wartości, 2,147,483,647
po której osiągnie stan przepełnienia i pętla się zakończy.
Najlepszym sposobem zrozumienia tego problemu jest przetestowanie prostego przykładu i zachowanie jego wyników.
Przykład :
for(int i = 10; i > 0; i++) {}
System.out.println("finished!");
Wynik:
finished!
BUILD SUCCESSFUL (total time: 0 seconds)
Po przetestowaniu tej nieskończonej pętli zakończenie zajmie mniej niż 1 sekundę.
for(int i = 10; i > 0; i++) {
System.out.println("infinite: " + i);
}
System.out.println("finished!");
Wynik:
infinite: 314572809
infinite: 314572810
infinite: 314572811
.
.
.
infinite: 2147483644
infinite: 2147483645
infinite: 2147483646
infinite: 2147483647
finished!
BUILD SUCCESSFUL (total time: 486 minutes 25 seconds)
W tym przypadku testowym zauważysz ogromną różnicę w czasie zamykania i kończenia działania programu.
Jeśli nie masz cierpliwości, pomyślisz, że ta pętla jest nieskończona i nie zakończy się, ale w rzeczywistości jej zakończenie i osiągnięcie stanu przepełnienia przy i
wartości zajmie kilka godzin .
Wreszcie, po umieszczeniu instrukcji print wewnątrz pętli for, doszliśmy do wniosku, że zajmie to znacznie więcej czasu niż pętla w pierwszym przypadku bez instrukcji print.
Czas potrzebny na uruchomienie programu zależy od specyfikacji komputera, w szczególności mocy obliczeniowej (pojemności procesora), systemu operacyjnego i IDE, które kompiluje program.
Testuję ten przypadek na:
Lenovo 2,7 GHz Intel Core i5
System operacyjny: Windows 8.1 64x
IDE: NetBeans 8.2
Zakończenie programu zajmuje około 8 godzin (486 minut).
Możesz również zauważyć, że krok zwiększa się w pętli for i = i + 1
jest bardzo wolnym czynnikiem, aby osiągnąć maksymalną wartość int.
Możemy zmienić ten współczynnik i przyspieszyć przyrost kroku, aby przetestować pętlę w krótszym czasie.
jeśli to umieścimy i = i * 10
i przetestujemy:
for(int i = 10; i > 0; i*=10) {
System.out.println("infinite: " + i);
}
System.out.println("finished!");
Wynik:
infinite: 100000
infinite: 1000000
infinite: 10000000
infinite: 100000000
infinite: 1000000000
infinite: 1410065408
infinite: 1215752192
finished!
BUILD SUCCESSFUL (total time: 0 seconds)
Jak widać, jest to bardzo szybkie w porównaniu z poprzednią pętlą
zakończenie i zakończenie działania programu zajmuje mniej niż 1 sekundę.
Po tym przykładzie testowym myślę, że powinno to wyjaśnić problem i udowodnić słuszność Zbynka Vyskovsky'ego - odpowiedź kvr000 , również będzie odpowiedzią na to pytanie .
x
rośnie szybciej niż zmienna pętlij
. Innymi słowy,j
nigdy nie osiągnie górnej granicy, stąd pętla będzie działać „na zawsze”. Cóż, nie na zawsze, najprawdopodobniej w pewnym momencie dojdzie do przepełnienia.