Chapter11_2. 제어문

YeongSeok·2022년 7월 27일
0

Java

목록 보기
16/25

1. 제어문

프로그램을 작성하다 보면, 처리 순서를 의도적으로 바꿔야 할 때가 있는데, 이 역할을 수행하는 것이 '제어문'이다.

  1. 제어문의 개념

    2개의 선택 제어문(if, switch)과 3개의 반복 제어문(for, while, do-while)으로 구성된 5개의 제어문과 2개의 제어 키워드(break, continue)가 존재

5개의 제어문은 모두 중괄호({})가 존재

2. if 선택 제어문

조건식에 따라 실행문의 실행 여부를 결정하는 선택 제어문

유형 1. if 단일 구문

조건식 1개, 중괄호 1개가 있는 구조

if (조건식) {
실행 구문;
}
변수가 포함된 조건식이 주로 사용
중괄호를 생략했을 때 제어문의 동작
모든 제어문은 중괄호를 포함하며, 이를 생략한 경우 컴파일러가 자동으로 삽입
컴파일러가 삽입하는 중괄호는 반드시 하나의 실행 구문만 감싼다.

if (3 > 5)
    System.out.println("hello!");	   
    System.out.println("world");	

해당 코드를 intellij에서 build하게 되면,
첫 출력문은 매번 false인 제어문에 의해 무시되고,
두번째 출력문만이 아래와 같이 test.class에 build된다.

public class test {
    public test() {
    }
    public static void main(String[] args) {
        System.out.println("world");
    }
}

유형 2. if-else 구문

조건식 하나와 중괄호 2개가 있는 구조

if (조건식) {
	실행 구문;
}
else {
	실행 구문;
}

모든 조건식은 true or false
조건식의 결괏값에 따라 둘 중 하나를 선택하는 제어문이므로 삼항 연산자와 상호 변환이 가능

유형 3. if-else if-else 구문

N개의 조건식과 N+1개의 중괄호를 포함하는 구조

if (조건식 1) {
	실행 구문;
}
else if (조건식 2) {
	실행 구문;
}
...
else if (조건식 N) {
	실행 구문;
}
else {
	실행 구문;
}

else if 구문은 개수에 상관없이 추가 가능
조건식을 검색할 때 항상 위에서부터 검사를 수행, 처음 참이 되는 블록 하나만 실행하고 if 문을 탈출
따라서, 다수의 조건식이 참이 나올 수 있는 때는 순서에 유의해 작성
조건식의 순서에 상관없이 항상 동일한 결과 도출을 위해서는 모든 조건식 중 하나의 조건식만 참이 나오도록 조건식을 좀 더 구체화

3. switch 선택 제어문

점프 위치 변숫값에 따라 특정 위치(case)로 이동해 구문을 실행하는 선택 제어문
점프할 수 있는 위치는 'case 위칫값:'으로 설정
또는 'default:' 구문으로 일치하는 위칫값이 없을 때 점프할 위치를 설정, 이는 생략 가능

이동할 위치를 가리키는 콜론(:) 문자는 삼항 연산자, case 구문, Label, 람다식에서 사용

switch 문의 역할은 특정 위치로 이동시키는 것이 전부

int a = 2;
switch(a) {
case 1:
	System.out.println("A");
case 2:
	System.out.println("B");
case 3:
	System.out.println("C");
default:
	System.out.println("D");
}

a 값이 2이므로 switch 문의 역할은 case 2: 로 실행 순서를 이동시키는 것
따라서 원래 프로그램 실행 순서대로 1줄씩 실행되어 B, C, D가 모두 출력
-> 조건식이 true인 첫 번째 블록 하나만 실행하는 if 문과 다른 점
break 제어 키워드 사용
if 문을 제외한 가장 가까운 중괄호({})를 탈출하는 키워드

int a = 2;
switch(a) {
case 1:
	System.out.println("A");
    break;
case 2:
	System.out.println("B");
    break;
case 3:
	System.out.println("C");
    break;
default:
	System.out.println("D");
}

case 구문 문법을 만들 때 break 기능이 추가되지 않은 이유
10점 만점에 7점 이상은 "Pass"를 출력하고 나머지는 "Fail"을 출력하려는 예시

int a = 8;
switch(a) {
case 10:
	System.out.println("Pass");
    break;
case 9:
	System.out.println("Pass");
    break;
case 8:
	System.out.println("Pass");
    break;
case 7:
	System.out.println("Pass");
    break;

default:
	System.out.println("Fail");
}

중복 코드가 많아 비효율적

int a = 8;
switch(a) {
case 10:
case 9:
case 8:
case 7:
	System.out.println("Pass");
    break;

default:
	System.out.println("Fail");
}

하나의 실행문에 여러 개의 case를 지정하면 훨씬 더 간결한 코드 작성 가능
switch 문은 위칫값으로 정수, 문자, 문자열만 사용 가능, if 문과 상호 변환 가능

switch 문과 if 문의 성능 차이
전체적인 속도의 차이는 거의 없다.
다만 각 결과에 따른 속도 차이는 존재할 수 있음

if 문에서는 결과 출력을 위해서 필요한 조건식의 비교가 조건식의 위치에 따라 달라져 속도 차이 발생 가능
switch 문에서는 어떤 case 이든 동일하게 한 번의 점프만을 수행한 후 실행되기에 모든 출력 속도가 동일

4. for 반복 제어문

실행 구문을 반복적으로 수행하는 반복 제어문으로, 반복 횟수가 정해질 때 주로 사용

for (초기식; 조건식; 증감식) {
실행 구문;
}

컴파일러는 문법적으로 for 문안의 소괄호 안에 세미콜론이 2개 있는지 여부만 검사
초기식: for 문이 시작될 때 딱 한 번만 실행된다. for 문 안에서만 사용할 변수는 주로 초기식에서 초기화
조건식: 실행 구문으로 들어가기 위한 유일한 출입구. 조건식의 결과가 true가 나오는 동안은 실행 구문을 반복하고 false인 경우 탈출하기에 for 문이 끝나는 위치는 닫힌 중괄호(})가 아닌 조건식이다.
증감식: for 문의 실행 구문이 모두 수행된 후 닫힌 중괄호(})를 만나면 다음 반복을 위해 다시 이동하는 위치로 매회 반복이 수행될 때마다 호출

초기식, 조건식, 증감식을 생략하더라도 세미콜론만 있으면 문법 오류는 발생하지 않는다.

조건식을 생략하면 컴파일러는 자동으로 조건식에 true를 삽입하여 구문을 끊임없이 반복하게 한다.
대부분 무한 루프 안에는 break 키워드를 삽입해 특정 조건을 만족했을 때 무한 루프를 탈출하도록 구현
Unreachable code(도달할 수 없는 코드)
무한 반복을 하는 코드 다음에 어떤 실행 코드를 작성하면 eclipse와 intellji는 문법 오류를 발생시키는데, 이는 무한 루프에 가로막혀 결코 도달할 수 없는 코드(unreachable code)를 작성했기 때문
조건식에 명시적으로 false를 넣으면 항상 for 문 안의 내용을 절대 실행할 수 없으므로 오류가 발생

for ( ; ; ) {
	실행 구문;
}
실행 구문;
> ```

for ( ; false; ) {
실행 구문; // 오류 발생
}


# 5. while 반복 제어문
중괄호 안의 실행 구문을 반복적으로 실행하는 반복 제어문
소괄호 안의 조건식이 true인 동안 반복은 지속
반복 횟수를 정하지 않고 특정 조건까지 반복하고자 할 때 주로 사용

초기식;
while (조건식) {
	실행 구문;
    증감식;
> }
초기식과 증감식은 생략 가능
초기식은 while 문 실행 이전에 정의돼야 하고, 증감식은 중괄호 안에 있어야 for 문과 동일하게 수행


먼저 조건식을 검사하고, 조건식이 true일 때 중괄호 안의 실행 구문을 실행
닫힌 중괄호를 만나면 다시 조건식을 검사
조건식이 거짓이 될 때까지 이를 반복
역시나 while 문이 종료되는 시점은 닫힌 중괄호가 아닌 조건식
for 문과 같이 반복 횟수가 지정돼 있을 때도 사용이 가능하여 초기식과 증감식의 작성 위치만 바꿔줌으로써 상호 변환 가능

while 문의 조건식에 true를 넣으면 무한 루프문이 되고, while 문에서는 for 문과 달리 조건식을 생략할 수 없다.
또한 for 문과 동일하게 Unreachable code에 대한 오류가 발생

# 6. do-while 반복 제어문
while 문과 매우 비슷한 반복 제어문으로, 조건식의 검사와 반복 실행의 순서에서만 차이가 존재

초기식;
do {
    실행 구문;
    증감식;
} while (조건식);
마지막이 중괄호로 끝나지 않으므로 제어문들 중 유일하게 세미콜론(;)이 필요


일단 do 구문을 실행한 후 조건식을 검사
조건식이 참이면 다시 do 구문을 실행
거짓이면 제어문을 탈출
while 문과 비교
while 문은 조건식을 먼저 검사하므로 최소 반복 횟수는 0(처음부터 조건식이 false일 때)
do-while 문은 일단 실행한 후 조건식을 검사하므로 최소 반복 회수가 1

int a;
// while
a = 0;
while (a < 10) {
System.out.print(a + " ");
a++;
}
System.out.println();

> // do-while
a = 0;
do {
    System.out.print(a + " ");
    a++;
} while(a < 10);

1회 이상 반복될 때 while 문과 do-while 문의 결과는 동일
while 문이 0번 반복할 때만 차이가 있고 1번 이상에서는 동일
7. 제어문의 중복
각 제어문 내부에는 또 다른 제어문을 포함 가능

5. 제어 키워드

  1. break 제어 키워드
    if 문을 제외한 가장 가까운 중괄호({})를 탈출하는 제어 키워드
    반복문에서 특정 조건을 만족할 때 반복문을 탈출하는 데 사용
    일반적으로 if 문과 함께 사용해 특정 조건이 만족될 때 반복문을 탈출하도록 구성
for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (j == 3)
            break;
        System.out.println("i+ "," + j");
    } // -> break로 탈출하는 중괄호
}

위와 같은 경우 break는 if 문을 제외한 가장 가까운 중괄호를 탈출하기에, 내부의 j 변수를 사용하는 내부 for 문만 탈출한다.

j = 3 일 때, 외부 for 문까지 탈출하기 위해서는
break를 수행하기 전에 외부 조건식이 false가 되도록 i 값을 큰 값으로 바꾼다.

for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
    	if (j == 3) {
            i = 100;
            break;
        }
        System.out.println("i+ "," + j");
    } // -> break로 탈출하는 중괄호
}

break로 탈출하는 중괄호는 동일하지만, 이후 i 값을 사용한 조건식에서 false가 나와 결국 이중 for 문을 모두 탈출
break + Label(레이블)
다중 반복문을 한 번에 탈출하는 자바의 공식적인 방법
break 다음에 레이블을 지정하면 한 번에 여러 개의 다중 반복문을 탈출할 수 있다.
레이블명은 개발자가 임의로 지을 수 있으며, 레이블 다음에는 반드시 콜론(:)을 표시해야 한다.

out:
for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if (j == 3)
            break out;
        System.out.println("i+ "," + j");
    }
}

break out 은 out 레이블이 위치해 있는 바깥쪽 for 문을 탈출하라는 의미

6. continue 제어 키워드

반복 제어문의 닫힌 중괄호(}) 역할을 하는 제어 키워드
조건식이 true가 돼 실행 구문을 실행한 후 닫힌 중괄호를 만나면 다시 다음 반복을 위해 증감식을 수행하거나(for 문) 조건식을 검사(while 문)

즉, 반복문 실행 도중 continue를 만나면 특정 구문을 실행하지 않고 건너뛰어 위의 과정을 수행

또한 Unreachable code에 대한 오류가 발생하고, break와 마찬가지로 continue + Label을 활용하여 한 번에 여러 개의 반복문을 건너뛸 수 있다.

POS1: // 레이블 위치 지정(continue하고자 하는 반복문 앞에 레이블 표기)

for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
    	if (j == 3) 
            continue POS1; // POS1 레이블이 달린 반복문의 닫힌 중괄호 대체
    System.out.println(i + "," + j);
    }
}

continue가 대체하는 중괄호는 레이블이 가리키고 있는 외부 for 문의 닫힌 중괄호이므로 i++ 의 증감식으로 바로 이동할 한다.

profile
끊임없이 성장하고 싶은 개발자

0개의 댓글