조건문과 반복문

황찬호·2021년 4월 27일

JAVA

목록 보기
2/5

조건문 - if, switch

1.1 if문

if문은 가장 기본적인 조건문이며, 다음과 같이 '조건식'과 '괄호{}'로 이루어져 있다.

if (조건식) {
	// 조건식이 참(true)일 때 수행될 문장들을 적는다.
}

만일 조건식 'score > 60'이 참이면 괄호 안의 문장이 수행되어 화면에 "합격입니다."라고 출력되고 거짓이면, if문 다음의 문장으로 넘어간다.

if (score > 60) {
	System.out.println("합격입니다.");
}

변수 score의 값을 80으로 가정하고 조건식이 평가되는과정을 살펴보면 다음과 같다.

score > 60
80 > 60
true

* 조건식을 사용할 때 실수하기 쉬운 것이, 등가비교 연산자 '=='대신 대입 연산자 '='를 사용하는 것이다. 예를 들어 'x가 0일 때 참'인 조건식은 'x==0'인데 'x=0'이라고 적는 경우가 있다.

1.2 if-else문

if (조건식) {
	// 조건식이 참일 때 수행될 문장
	} else {
	// 조건식이 거짓일 때 수행될 문장
	}

1.3 if-else if문

if (조건식1) {
	// 조건식1의 결과가 참일 때 수행될 문장
	} else if (조건식2) {
	// 조건식2의 결과가 참일 때 수행될 문장
	} else if (조건식3) {
	// 조건식3의 결과가 참일 때 수행될 문장
	} esle {
	// 위의 어느 조건식도 만족하지 않을 때 수행될 문장
	}

1.4 중첩 if문

if (조건식1) {
	// 조건식1의 결과가 참일 때 수행될 문장
	if (조건식2) {
	// 조건식1과 조건식2가 모두 참일 때 수행될 문장
	} else {
	// 조건식1이 참이고, 조건식2가 거짓일 때 수행될 문장
	}
} else {
// 조건식1이 거짓일 때 수행될 문장
}

1.5 switch문

if문은 조건식의 결과가 참과 거짓, 두가지 밖에 없기 때문에 경우의 수가 많아질수록 else-if를 계속 추가해야하므로 조건식이 많아져서 복잡해지고, 여러개의 조건식을 계산해야하므로 처리시간도 많이 걸린다.
하지만 if문과는 달리 switch문은 단 하나의 조건식으로 많은 경우의 수를 처리할 수 있다.
다만 switch문은 제약조건이 있기 때문에, 경우의 수가 많아도 어쩔 수 없이 if문으로 작성해야 하는 경우가 있다.

* switch문은 항상 if문으로 변환이 가능하지만, if문은 switch문으로 작성할 수 없는 경우가 있다.

switch (조건식) {
	case1 :
		// 조건식의 결과가 값1과 같을 경우 수행될 문장
		break;
	case2 :
    		// 조건식의 결과가 값2와 같을 경우 수행될 문장
        	break;
    	// case 값3 ...
        default :
        	// 조건식의 결과와 일치하는 case문이 없을 때 수행될 문장
}

break문은 각 case문의 영역을 구분하는 역할을 하는데 빼먹는 실수를 하지 않도록 주의해야 한다.
그러나 경우에 따라서는 다음과 같이 고의적으로 break문을 생력하는 경우도 있다.

switch (level) {
    case 3 :
    	grantDelete();	// 삭제권한을 준다.
    case 2 :
    	grantWrite();	// 쓰기권한을 준다.
    case 3 :
    	grantRead();	// 읽기권한을 준다.
    }

switch문의 제약조건

- switch문의 조건식은 결과값이 반드시 정수 or 문자열이어야 하며, 이 값과 일치하는 case문으로 이동하기 때문에 case문의 값 역시 정수 or 문자열이어야 한다. (JDK1.7이전에는 문자열이 허용안됨)
- case문의 값을 반드시 상수이어야 한다. 변수나 실수는 case문의 값으로 사용할 수 없다.

public static void Main(String[] args) {
	int num, result;
	final int ONE = 1;
	// ...
	switch(result) {
	case '1':		// OK. 문자 상수(정수 상수 49와 동일)
	case ONE:		// OK. 정수 상수
	case "YES":		// OK. 문자열 상수. JDK 1.7부터 허용
	case num:		// Error. 변수는 불가
	case 1.0:		// Error. 실수도 불가	
	}
}

switch문의 활용

- 계절 알리미

import java.util.Scanner;

public class FlowEx6 {

	public static void main(String[] args) {
		int month = 0;
		
		System.out.print("현재 월을 입력하세요.>");
		
		Scanner sc = new Scanner(System.in);
		String tmp = sc.nextLine();		// 화면을 통해 입력받은 내용을 tmp에 저장
		month = Integer.parseInt(tmp);	// 입력받은 문자열(tmp)을 숫자로 변환
		
		switch(month) {
		case 3:
		case 4:
		case 5:
			System.out.println("현재 계절은 봄입니다.");
			break;
		case 6: case 7: case 8:
			System.out.println("현재 계절은 여름입니다.");
			break;
		case 9: case 10: case 11:
			System.out.println("현재 계절은 가을입니다.");
		case 12: case 1: case 2:
			System.out.println("현재 계절은 겨울입니다.");
		}

	}

}

- 가위바위보

import java.util.Scanner;

public class FlowEx7 {

	public static void main(String[] args) {
		int user, com;
		
		System.out.println("가위(1), 바위(2), 보(3) 중 하나를 입력하세요.>");
		
		Scanner sc = new Scanner(System.in);
		String tmp = sc.nextLine();
		user = Integer.parseInt(tmp);
		
		com = (int) (Math.random() * 3) + 1;	// 1, 2, 3중 하나가 com에 저장됨
		
		System.out.println("당신은 " + user + "입니다.");
		System.out.println("컴은 " + com + "입니다.");
		
		switch(user-com) {
		case 2: case -1:
			System.out.println("당신이 졌습니다.");
			break;
		case 1: case -2:
			System.out.println("당신이 이겼습니다.");
			break;
		case 0:
			System.out.println("비겼습니다.");
//			break;	// 마지막 문장이므로 break를 사용할 필요가 없다.
		}

	}

}

반복문 - for, while, do-while

2.1 for문

for문의 구조

for문은 아래와 같이 '초기화', '조건식', '증감식', '블럭{}'으로 이루어져있다. 조건식이 참인 동안 블럭{}내의 문장들을 반복하다 거짓이 되면 반복문을 벗어난다.

for(int i=1; i<=5; i++) { // (초기화; 조건식; 증감식) 
	System.out.println("Hello world!"); // 조건식이 참일 때 수행될 문장
}

초기화

반복문에 사용될 변수를 초기화하는 부분이며 처음에 한번만 수행된다. 보통 변수 하나로 for문을 제어하지만 둘 이상의 변수가 필요할 때는 아래와 같이 콤마',' 구분자로 변수를 초기화 하면 된다. 단, 두 변수의 타입은 같아야 한다.

for(int i=1; i<=10; i++) {...} // 변수 i의 값을 1로 초기화한다.
for(int i=1, j=0; i<=10; i++) {...} // int타입의 변수 i와 j를 선언하고 초기화

증감식

반복문을 제어하는 변수의 값을 증가 또는 감소시키는 식이다. 변수의 값을 1씩 증가시키는 연산자'++'이 증감식에 주로 사용되지만, 다음과 같이 다양한 연산자들로 증감식을 작성할 수 있다.

for(int i=1; i<=10; i++) // 1부터 10까지 1씩 증가
for(int i=1; i<=10; i--) // 1부터 10까지 1씩 감소
for(int i=1; i<=10; i+=2) // 1부터 10까지 2씩 증가
for(int i=1; i<=10; i*=3) // 1부터 10까지 3배씩 증가

증감식도 콤마',' 를 이용해서 두 문장 이상을 하나로 연결해서 쓸 수 있다.

for (int i=1, j=10; i<=10; i++, j--) {...}	// i는 1부터 10까지 1씩 증가
						// j는 10부터 1까지 1씩 감소

효율적으로 변수 활용하기

다양한 연산자를 이용해서 짝수(2*i), 홀수(2*i-1), 제곱(i*i), 역순(11-i), 순환(i%3) ,반복(i/3)을 구하는 방법이다.


public class FlowEx15 {

	public static void main(String[] args) {
		System.out.println("i \t 2*i \t 2*i-1 \t i*i \t 11-i \t i%3 \t i/3");
		System.out.println("-----------------------------------------------------");
		
		for(int i=1; i<=10; i++) {
			System.out.printf("%d \t %d \t %d \t %d \t %d \t %d \t %d\n", i, 2*i, 2*i-1, i*i, 11-i, i%3, i/3);
			
		}
	}
}

for문의 활용

- 1부터 10까지 합 구하기


public class FlowEx13 {

	public static void main(String[] args) {
		int sum = 0; // 합계를 저장하기 위한 변수
		
		for (int i=1; i<=10; i++) {
			sum += i; // sum = sum + i;
			System.out.printf("1부터 %2d까지의 합: %2d\n", i, sum); // %2d로 두칸만보여주며 우측정렬
		}
	}
}

중첩 for문

if문 안에 또 다른 if문을 넣을 수 있는 것처럼, for문 안에 또 다른 for문을 포함시키는 것도 가능하다. 그리고 중첩의 횟수는 거의 제한이 없다.

향상된 for문

JDK1.5부터 배열과 컬렉션에 저장된 요소에 접근할 때 기존보다 편리한 방법으로 처리할 수 있도록 for문의 새로운 문법이 추가되었다.

for(타입 변수명: 배열 또는 컬렉션) {
	// 수행할 문장

위의 문장에서 타입은 배열 또는 컬렉션의 요소의 타입이여야 한다. 배열 또는 컬렉션의 저장된 값이 매 반복마다 하나씩 순서대로 읽혀서 변수에 저장된다. 그리고 반복문의 괄호{}내에서는 이 변수를 사용해서 코드를 작성한다.

아래와 같이 배열arr이 선언되어 있을 때,

int[] arr = { 10, 20, 30, 40, 50};

이 배열의 모든 요소를 출력하는 for문은 아래와 같다.

for(int i=0; i < arr.length; i++) {
	System.out.println(arr[i]);
    }
//	위와 아래의 코드는 같다.
for(int tmp : arr) {
	System.out.println(tmp);

두 for문은 동등하며, 향상된 for문이 더 간결하다는 것을 알 수 있다.
그러나 향상된 for 문은 일반적인 for문과 달리 배열이나 컬렉션에 저장된 요소들을 읽어오는 용도로만 사용할 수 있다는 제약이 있다.

향상된 for문 활용
public class FlowEx22 {

	public static void main(String[] args) {
		int[] arr = { 10, 20, 30, 40, 50};
		int sum = 0;
		
		for(int i=0; i < arr.length; i++) {
			System.out.printf("%d ", arr[i]);
		}
		System.out.println();
		
		for(int tmp : arr) {
			System.out.printf("%d ", tmp);
			sum += tmp;
		}
		System.out.println();
		System.out.println("sum = " + sum);
	}
}

2.2 while문

for문에 비해 while문은 구조가 간단하다. if문 처럼 조건식과 블럭{}만으로 이루어져 있다. 다만 if문과 달리 while문은 조건식이 '참인 동안', 즉 조건식이 거짓이 될 때 까지 블럭{}내의 문장을 반복한다.

int i=1; // 초기값

while (i<=10) { // 조건식
	// 조건식의 결과가 참인 동안, 반복될 문장
    i++; // 증감값
    }    

for문은 초기값, 조건값, 증감값을 한 곳에 모아 놓은 것일 뿐, while문과 다르지 않다. 그래서 for문과 while문은 항상 서로 변환이 가능하다. 상황에 따라 for문이 적절할 수도, while문이 적절할 때가 있다.

2.3 do-while문

do-while문은 while문의 변형으로 기본적인 구조는 while문과 같으나 조건식과 블럭{}의 순서를 바꿔놓은 것이다. 그래서 while문과반대로 블럭{}을 먼저 수행한 후에 조건식을 평가한다. while문은 조건식의 결과에 따라 블럭{}이 한번도 수행되지 않을 수 있지만, do-while문은 최소한 한번은 수행될 것은 보장한다.

do {
	// 조건식의 결과가 참일 때 수행될 문장
} while (조건식);

2.4 break문

berak문은 자신이 포함된가장 가까운 반복문을 벗어난다. 주로 if문과 함께 사용되어 특정 조건을 만족하면 반복문을 벗어나도록 한다.

while(true) {
	if(sum > 100)
    		break;
    	// 문장들...;
        // break문이 수행되면 이 부분들은 실행되지 않고 while문을 완전히 벗어난다.
       }

2.5. continue문

continue문은 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복으로 넘어간다. for문의 경우 증감식으로, while문과 do-while문의 경우 조건식으로 이동한다.
전체 반복 중에 특정조건을 만족하는 경우를 제외하고자 할 때 유용하다.

for(int i=0; i<=10; i++) {
	if (i%3==0) {
            continue;
            // 문장들...;
            // continue문이 수행되면 이 부분들이 수행되지 않고 다음 반복으로 넘어간다.
        }
}

* break문과 달리 반복문을 벗어나지 않는다.

2.6 이름 붙은 반복문

기회가 생기면 해보겠다.

profile
천천히 그리고 꾸준히

0개의 댓글