JAVA/조건문(if, switch)과 반복문(for, while)

[JAVA] while문

prize1209 2021. 6. 12. 05:45

1. while문

 

조건식과 수행할 블럭{} 또는 문장으로 구성

while문은 먼저 조건식을 평가해서 조건식이 거짓이면 문장 전체를 벗어나고,

참이면 블럭{}내의 문장을 수행하고 다시 조건식으로 돌아간다.  조건식이 거짓이 될 때까지 이 과정을 반복한다.

 

 

 

for문과 while문의 비교

1부터 10까지 정수를 출력

for문과 while문은 항상 서로 변환 가능하다. 만일 초기화나 증감식이 필요하지 않은 경우라면 while문이 더 적합하다.

 

 

while문의 조건식은 생략 불가

 

while문의 조건식이 항상 참이 되게 하려면 true를 반드시 넣어야한다. 다음의 두 반복문은 블럭{} 내의 문장을 무한반복.

 

//무한반복

 

 

예23)

public class FlowEx23 {
	public static void main(String[] args) {
		int i=5; 
		while(i--!=0) {
			System.out.println(i+"- I can do it");
		}
	}
}

while문의 조건식 ' i--!=0 ' 는 i의 값이 0이 아닌 동안만 참이고, i의 값이 계속 감소하다 0이 되면 거짓이 되어 while문을 빠져나간다. 

 

i-- 가 후위형이므로 조건식이 평가된 후에 i의 값이 감소된다는 것에 유의.

예를 들어, i의 값이 1일때는 조건식이 평가된 후에 감소되어 0이 된다. 그래서 5~1 이 아닌 4~0 이 출력된다.

 

 

 

감소 연산자 분리

 

 

--i 같은 전위형은 감소 연산자가 조건식에서 분리되면 while문을 벗어나기 때문에 전과 다른 문장이 된다.

아래 while문은 반복을 거듭해도 i의 값이 감소하지 않아서 조건식이 결코 거짓이 될 수 없다. 

 

public class FlowEx23 {
	public static void main(String[] args) {
		int i=5; 
		  
		while(--i!=0) {
			System.out.println(i+"- I can do it");
		}
	}
}

예상한대로 평가전 먼저 감소시키기 때문에 4부터 1까지 출력. 

 

but, 왼쪽 예는 실행 시 무한반복에 빠져버린다.

public class FlowEx23 {
	public static void main(String[] args) {
		int i=5; 
		--i;  
		while(i!=0) {
			System.out.println(i+"- I can do it");
		}
	}
}

 

 

 

예24) 카운트다운

public class FlowEx24 {
	public static void main(String[] args) {
		int i = 11;
		System.out.println("카운트 다운을 시작합니다");
		while (i > 0) {
			i--;
			System.out.println(i);
		}
		System.out.println("GAME OVER");
	}
}

 

만약 출력 시간이 약간씩 지연되도록 하려면  

 

public class FlowEx24 {
	public static void main(String[] args) {
		int i = 11;
		System.out.println("카운트 다운을 시작합니다");
		while (i--!=0) {
			System.out.println(i);
			for(int j=0; j<2_000_000_000; j++){
				;  //아무런 내용도 없는 빈 문장
			}
		}
		System.out.println("GAME OVER");
	}
}
for(int j=0; j<2_000_000_000; j++){
;  //아무런 내용도 없는 빈 문장
}

for문의 블럭{} 내에는 아무 일도 하지 않는 빈 문장 하나만 있을 뿐 그외에는 아무 것도 없다. 그저 조건식과 증감식을 2,000,000,000번 반복하면서 시간을 보낼 뿐.

 

블럭 내에 문장이 하나뿐일 때 괄호{}를 생략할 수 있으므로 위의 for문을 다음과 같이 바꿀 수 있다. 

for(int j=0; j<2_000_000_000; j++);  

 

만약 실수로 아래처럼 작성하면 빈 문장 ';'만 for문에 속한 것으로 간주되어 블럭{}은 반복되지 않는다. 단 한번만 수행된다. 

public class FlowEx24_1 {
	public static void main(String[] args) {
		int i; //i를 선언해줘야한다. 
		for(i=1; i<=10; i++); { //빈 문장 ';'를 10번 반복한다. 
			System.out.println("i="+i); // i=11이 출력된다. 
		}
	}
}

for문은 i의 값이 11일 때 조건식이 거짓이 되어 반복을 마치므로 i의 값은 11이 된다.

 

 

예25) //각 자리수 합 출력

import java.util.*;

public class FlowEx25 {
	public static void main(String[] args) {
		int num=0, sum=0; //num과  sum을 초기화
		System.out.print("숫자를 입력하세요(예:12345)>");
		Scanner sc = new Scanner(System.in);
		String tmp = sc.nextLine(); //화면을 통해 입력받은 내용을 tmp에 저장
		num = Integer.parseInt(tmp); //입력받은 문자열(tmp)을 숫자로 변환
		
		while(num!=0) {
			//num을 10으로 나눈 나머지를 sum에 더함
			sum+=num%10; //sum=sum+num%10;
			System.out.printf("sum=%3d num=%d%n", sum, num);
			num/=10; //num=num/10; num을 10으로 나눈 값을 다시 num에 저장 
		}
		System.out.println("각 자리수의 합:"+sum); 	
		//while문이 끝나고 마지막 sum 출력
		}

받은 수를 10으로 나머지 연산하면 마지막 자리를 얻는다. 그리고 10으로 나누면 마지막 자리를 제거할 수 있다. 

12345%10 -> 5

12345/10 -> 1234

 

그래서 입력받은 숫자 num을 0이 될 때까지 반복해서 10으로 나눠가면서, 10으로 나머지 연산을 하면 num의 모든 자리를 얻을 수 있다. 

 

이 과정을 단계별로 살펴보면

num num%10 sum=sum+num%10
(sum+=num%10)
num=num/10
(num/=10)
12345 5 5=0+5 1234=12345/10
1234 4 9=5+4 123=1234/10
123 3 12=9+3 12=123/10
12 2 14=12+2 1=12/10
1 1 15=14+1 0=1/10
0 - - -

num, sum 모두 초기화 먼저 해줘야한다는 것과 

num을 받아 sum을 계산하고 출력한뒤, num/10을 해준다는 것! 순서에 주의하자! 

그 num/10 한 값이 다시 while문으로 num으로 들어가면서 반복문이 돈다! 

그리고 while문이 끝나고 sum을 출력하면 마지막 sum이 출력된다. 

num의 값은 'num/=10'에 의해서 한자리씩 줄어들다가 0이 되면, while문의 조건식이 거짓이 되어 반복문을 종료한다. 

 

 

 

 

예26) //num-sum출력

 

1) num 13까지 sum값 구하기

import java.util.*;

public class FlowEx26 {
	public static void main(String[] args) {
		int num=1, sum=0;
		
		while(num<=13) {
			sum+=num;
			  //num을 1씩 증가시켜주는 것 잊지말기! 
			System.out.println(num+"-"+sum);
			num++;
		}
	}
}

   num =1  sum =0+1   출력-> 1-1 ->num 1증가

->num=2   sum =2+1   출력-> 2-3 ->num 1증가

->num=3   sum =3+3   출력-> 3-6 ->num 1증가

이런 식으로 반복해서 num이 13이 되면 while문을 실행하고 sum = 91 ->출력이 된다. -> num이 1증가해 14가 된다.

num=14이므로 조건식이 거짓이라서 while문 수행 불가.

 

 

2) num이 몇 이면 sum <=100 인지 구하기

 

public class FlowEx26_2 {
	public static void main(String[] args) {
		int num=0, sum=0;
		
		while((sum+= ++num)<=100) {
			//전위형으로 먼저 num을 증가시킴. sum = sum+ ++num
		System.out.printf("%d - %d%n", num, sum);
		}
	}
}

 

(sum += ++num) <=100 이 복잡한데 아래 두 식을 하나로 합쳐놓은 것이다.

 

sum +=++num //num의 값을 1증가시켜서 sum에 누적

sum<=100 //sum의 값이 100보다 작거나 같은지 확인

-> sum = sum+ ++num

 

 

 

예27)