IT

System.out.println이 사용되지 않는 한 끝없는 루프가 종료됩니다.

lottoking 2020. 9. 11. 08:15
반응형

System.out.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);

끝없는 루프가되고 이유를 모르겠습니다. 자바는 무한 루프를 인식하고 첫 번째 상황에서는 건너 뛰지 만 두 번째 상황에서는 메소드 호출을 실행해야 예상대로 작동합니까? 혼란스러워 :)


두 가지 예 모두 끝이 없습니다.

문제는 intJava (또는 거의 다른 공통 언어) 유형 제한입니다 . 의 값이 x도달하면 0x7fffffff양수 값을 추가하면 오버플로가 발생하고 x는 음수가되어보다 처리 j됩니다.

첫 번째와 두 번째 루프의 차이점은 내부 코드가 훨씬 더 많은 시간이 걸리고 x오버플로 가 거의 때까지 몇 분 정도 걸릴 수있는 것입니다 . 첫 번째 예의 경우 두 번째 미만이 소요될 수 있고 효과가 없기 때문에 최적화 프로그램에 의해 코드가 제거 가능성이 될 수 있습니다.

논의에서 언급했듯이 시간은 OS가 출력을 버퍼링하는 방법, 터미널 에뮬레이터로 출력하는지 여부에 따라 크게 달라 지 몇 분보다 훨씬 수 있습니다.


int로 선언되기 때문에 최대 값에 도달하면 x 값이 음수가되어 루프가 중단됩니다.

그러나 System.out.println이 루프에 추가 실행 속도가 표시됩니다 (콘솔에 출력하면 실행 속도가 느려짐). 그러나 두 번째 프로그램 (루프 내부에 시스템이있는 프로그램)이 충분히 오래 실행 가능하면 첫 번째 프로그램 (루프 내부에 시스템이없는 프로그램)과 동일한 동작을 가져옵니다.


여기에는 두 가지 이유가 있습니다.

  1. Java는 for루프를 최적화하고 루프 x후를 사용하지 않기 때문에 루프를 제거하기 만하면됩니다. System.out.println(x);루프 가방 문 을 넣어이를 확인할 수 있습니다 .

  2. Java가 실제로 루프를 최적화하지 않고 프로그램을 실행하고 결국 x너무 커져서 int오버플로가 보관 수 있습니다. 정수 오버플로는 대부분의 경우 정수 x를 j보다 작은 음수로 만들어 루프에서 나와 값을 인쇄합니다 y. System.out.println(x);루프 내 추가하여 확인할 수도 있습니다 .

또한 첫 번째 경우에도 결국 오버플로가 발생하여 두 번째 경우에도 마찬가지입니다.


둘 다 무한 루프가 실행, 처음에는 j = 0, j <x, j 증가 (j ++) 및 j는 정수 루프가 최대 값에 도달 할 때까지 실행 된 다음 오버플로 (An Integer Overflow가 조건입니다 ) 곱하기 또는 더하기와 같은 산술 연산의 결과가이를 저장하는 데 사용 된 정수 유형의 최대 크기를 초과 할 때 발생합니다.) 두 번째 예의 경우 시스템은 루프가 중단 될 때 y 값을 인쇄합니다.

무한 루프의 예를 보유하고있는 다음과 같이 보일 것입니다.

int x = 6;

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

(x)는 고유 한 10의 값을 얻지 못하기 때문입니다.

이중 루프로 무한 루프를 만들 수도 있습니다.

int i ;

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

첫 번째 for 루프가 i <10이라고 말하고 두 번째 for 루프로 들어가고 두 번째 for 루프가 == 5가 될 때까지 (i) 값을 증가시키기 때문에이 루프는 무한합니다. 그런 다음 첫 번째 for 루프로 진행합니다. i <10이기 때문에 for 루프 다시, 두 번째 for 루프 후에 재설정되기 때문에 프로세스가 계속 반복됩니다.


한 번 x초과 하는 값 2,147,483,647(의 최대 값 int) xjy를 인쇄하든 인쇄하지 않든 음수가되고 더 이상 크지 않기 때문에 유한 루프 입니다.

yto 의 값을 변경하고 루프에서 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.7GHz 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 초도 걸리지 않습니다.

이 테스트 예제 이후 나는 문제를 명확히하고 Zbynek Vyskovsky-kvr000의 답변의 타당성을 증명해야한다고 생각하며 , 또한이 질문에 대한 답변이 될 것 입니다.

참고 URL : https://stackoverflow.com/questions/41972103/seemingly-endless-loop-terminates-unless-system-out-println-is-used

반응형