[Java] Java의 정석 | Chapter 04 조건문과 반복문

숙취엔 꿀물.·2023년 11월 29일

Java

목록 보기
4/13
post-thumbnail

👉 1. 조건문 - if, switch

1.1 if 문

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

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

조건식

조건식조건식이 참일 조건
90 <= x && x <= 100정수 x가 90이상 100이하일 때
x < 0 || x > 100정수 x가 0보다 작거나 100보다 클 때
x%3==0 && x%2!=0정수 x가 3의 배수지만, 2의 배수는 아닐 때
ch=='y' || ch=='Y'문자 ch가 'y'또는 'Y'일 때
'a'<=ch && ch<='z'문자 ch가 소문자일 때
str.equals("yes")문자열 str의 내용이 "yes"일 때(대소문자 구분)

블럭{}

괄호{}를 이용해서 여러 문장을 하나의 단위로 묶을 수 있는데, 이것을 '블럭(block)'이라 고 한다. 아래와 같이 두 가지 스타일을 사용할 수 있다.

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

if (score <= 60)
{
	System.out.println("불합격입니다.");
}
  • 위의 스타일은 라인 수가 짧아진다는 장점이, 아래의 스타일은 블럭의 시작과 끝을 찾기 쉽다는 장점이 있다.
  • {} 안에 한 문장만 넣거나 아무런 문장을 넣지 않을 때는 괄호{}를 생략할 수 있다.

1.2 if-else 문

1.3 if-else if 문

두 가지 경우의 수를 처리할 때는 if-else 문을, 처리해야할 경우의 수가 셋 이상인 경우에는 아래와 같이 if-else if 문을 사용하면 된다.

if (조건식1) {
	// 조건식1의 연산결과가 참일 때 수행될 문장들을 적는다.
} else if (조건식2) {
	// 조건식2의 연산결과가 참일 때 수행될 문장들을 적는다.
} else if (조건식3) {
	// 조건식3의 연산결과가 참일 때 수행될 문장들을 적는다.
} else {
	// 위의 어느 조건식도 만족하지 않을 때 수행될 문장들을 적는다.
}
// 마지막에는 보통 else 블럭으로 끝나며, 경우에 따라 생략 가능하다.

1.4 중첩 if 문

if 문의 블럭 내에 또 다른 if 문을 포함시키는 것이 가능한데 이것을 중첩 if 문이라고 부르며 중첩의 횟수에는 거의 제한이 없다.

if (조건식1) {
	// 조건식1의 연산결과가 true일 때 수행될 문장들을 적는다.
    if (조건식2) {
    	// 조건식1과 2가 모두 true일 때 수행될 문장들
    } else {
    	// 조건식1이 true이고, 조건식2가 false일 때 수행되는 문장들
    }
} else {
	// 조건식1이 false일 때 수행되는 문장들
}

1.5 switch문

  • if 문은 경우의 수가 많아질수록 else-if를 계속 추가해야하므로 조건식이 많아져서 복잡해지고, 여러 개의 조건식을 계산해야하므로 처리시간도 많이 걸린다.
  • 이러한 if문과 달리 switch문은 단 하나의 조건식으로 많은 경우의 수를 처리할 수 있고, 표현도 간결하므로 알아보기 쉽다.
  • 다만 switch문은 제약조건이 있어 어쩔 수 없이 if문으로 작성해야 하는 경우가 있다.
1. 조건식을 계산한다.
2. 조건식의 결과와 일치하는 case문으로 이동한다.
3. 이후의 문장들을 수행한다.
4. break문이나 switch문의 끝을 만나면 switch문 전체를 빠져나간다.
switch (조건식) {
	case 값1 :
    	// 조건식의 결과가 값1과 같을 경우 수행될 문장들
        // ...
        break;
    case 값2 :
    	// 조건식의 결과가 값1과 같을 경우 수행될 문장들
        // ...
        break;
    // ...
    default:
    	// 조건식의 결과와 일치하는 case문이 없을 때 수행될 문장들
        // ...
}
  • 여기서 중요한 것이 있는데 break문은 각 case문의 영역을 구분하는 역할을 하는데, 만일 break문을 생략하면 case문 사이의 구분이 없어지므로 다른 break문을 만나거나 switch문 블럭{}의 끝을 만날 때까지 나오는 모든 문장들을 수행한다.

switch문의 제약조건

1. switch문의 조건식 결과는 정수 또는 문자열이어야 한다.
2. case문의 값은 정수 상수만 가능하며, 중복되지 않아야 한다.

<switch문 사용 예시>

import java.util.*;

public class FlowEx7 {
    public static void main(String[] args) {
        System.out.print("가위(1), 바위(2), 보(3) 중 하나를 입력하세요. > ");

        Scanner sc = new Scanner(System.in);
        int user = sc.nextInt(); // 화면을 통해 입력받은 숫자를 user에 저장
        int 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;
        }
    }
}

switch문의 중첩

import java.util.Scanner;

public class FlowEx11 {
    public static void main(String[] args) {
        System.out.println("당신의 주민번호를 입력하세요. Ex) 011231-1111222 : ");
        
        Scanner sc = new Scanner(System.in);
        String regNo = sc.nextLine();
        char gender = regNo.charAt(7); // 입력받은 번호의 8번째 문자를 gender에 저장
        
        switch(gender){
            case '1': case'3':
                switch(gender){
                    case '1':
                        System.out.println("당신은 2000년 이전에 출생한 남자입니다.");
                        break;
                    case '3':
                        System.out.println("당신은 2000년 이후에 출생한 남자입니다.");
                }
                break;
            case '2': case '4':
                switch(gender){
                    case '2':
                        System.out.println("당신은 2000년 이전에 출생한 여자입니다.");
                        break;
                    case '4':
                        System.out.println("당신은 2000년 이후에 출생한 여자입니다.");
                        break;
                }
                break;
            default:
                System.out.println("유효하지 않은 주민등록번호입니다.");
        }
    }
}


👉 2. 반복문 - for, while, do-while

2.1 for문

  • for문은 아래와 같이 '초기화', '조건식', '증감식', '블럭{}', 모두 4부분으로 이루어져 있으며, 조건식이 참인 동안 블럭{} 내의 문장들을 반복하다 거짓이 되면 반복문을 벗어난다.
for (①초기화;②조건식;④증감식) {
	// 조건식이 참일 때 ③수행될 문장들을 적는다.
}

제일 먼저 '①초기화'가 수행되고, 그 이후부턴는 조건식이 참인 동안 '②조건식 -> ③수행될 문장 -> ④증감식'의 순서로 계속 반복된다. 그러다가 조건식이 거짓이 되면, for문 전체를 빠져나가게 된다.

다음은 반복문의 단골손님인 구구단을 출력하는 예제이다.

public class FlowEx18 {
    public static void main(String[] args) {
        for (int i = 2; i <= 9; i++)
            for (int j = 1; j <= 9; j++)
                System.out.printf("%d x %d = %d\n", i, j, i * j);
    }
}

내부 문장의 개수에 따라 위처럼 괄호{}도 생략이 가능하다.

향상된 for문(enhanced for statement)

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

for (타입 변수명 : 배열 또는 컬렉션) {
	// 반복할 문장
}
  • 위의 형태와 같이 사용하는데 자세한 예시를 보여주면 아래의 두 반복문은 같은 의미이다.
for(int i=0; i<arr.length; i++){
	System.out.println(arr[i]);
}

for(int tmp : arr){
	System.out.println(tmp);
}

2.2 while문

while문은 조건식이 참(true)인 동안, 즉 조건식이 거짓이 될 때까지 블럭{} 내의 문장을 반복한다.

while (①조건식) {
	// 조건식의 연산결과가 참(true)인 동안, ②반복될 문장들을 적는다.
}
  • while문의 수행순서는 다음과 같다.
  1. 조건식이 참(true)이면 블럭{}안으로 들어가고, 거짓(false)이면 while문을 벗어난다.
  2. 블럭{}의 문장을 수행하고 다시 조건식으로 돌아간다.

for문과 while문의 비교

// 초기화, 조건식, 증감식
for(int i=1; i<=10; i++){
	System.out.println(i);
}


int i=1; // 초기화

while(i<=10){ // 조건식
	System.out.println(i);
    i++; // 증감식
}

while문의 조건식은 생략불가

for문은 조건식이 없으면 항상 참이되어 무한 반복하지만, while문은 조건식이 항상 참이 되도록 하려면 반드시 true를 넣어야 한다.


2.3 do-while문

do-while문은 while문의 변형으로 기본적인 구조는 while문과 같으나 조건식과 블럭{}의 순서를 바꿔놓은 것이다. 그래서 while문과 반대로 블럭{}을 먼저 수행한 후에 조건식을 평가한다.

do {
	// 조건식의 연산결과가 참일 때 수행될 문장들을 적는다.
} while (조건식);  <- 끝에 ';'을 잊지 않도록 주의
import java.util.Scanner;

public class FlowEx28 {
    public static void main(String[] args) {
        int input = 0, answer = 0;

        answer = (int) (Math.random() * 100) + 1; // 1~100 사이의 임의의 수를 저장
        Scanner sc = new Scanner(System.in);

        do {
            System.out.print("1과 100사이의 정수를 입력하세요.> ");
            input = sc.nextInt();

            if (input > answer) {
                System.out.println("더 작은 수로 다시 시도해보세요.");
            } else if (input < answer) {
                System.out.println("더 큰 수로 다시 시도해보세요.");
            }
        } while (input != answer);

        System.out.println("정답입니다.");
    }
}

2.4 break문

앞서 switch문에서 break문에 대해 배웠던 것처럼, break문은 자신이 포함된 가장 가까운 반복문을 즉시 벗어난다.


2.5 continue문

  • continue문은 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복으로 넘어간다.

  • for문의 경우 증감식으로 이동하며, while문과 do-while문의 경우 조건식으로 이동한다.

  • 반복문 전체를 벗어나지 않고 다음 반복을 계속 수행한다는 점이 break문과 다르다.

public class FlowEx31 {
    public static void main(String[] args) {
        for (int i = 0; i <= 10; i++) {
            if (i % 3 == 0)
                continue; // 조건식이 참이 되어 continue문이 수행되면 블럭의 끝으로 이동한다.

            System.out.println(i);
        }
    }
}

2.6 이름 붙은 반복문

  • break문은 근접한 단 하나의 반복문만 벗어날 수 있기 때문에, 여러 개의 반복문이 중첩된 경우에는 break문으로 중첩 반복문을 완전히 벗어날 수 없다.

  • 이때는 중첩 반복문 앞에 이름을 붙이고 break문과 continue문에 이름을 지정해 줌으로써 하나 이상의 반복문을 벗어나거나 반복을 건너뛸 수 있다.

profile
단단하게 오래가고자 하는 백엔드 개발자

0개의 댓글