4. 제어문(Control Flow Statements)
1. 키워드
- 제어문(Control Flow Statements)
- 조건문(Conditional Statements)
- 반복문(Iteration Statements)
continue
문과break
문- 이름을 가지는 반복문(Break with Label)
2. 조건문(Conditional Statements)
1) 제어문(Control Flow Statements)
- 프로그램이 원하는 결과를 얻기 위해서는 프로그램의 순차적인 흐름을 제어해야만 할 경우가 생긴다.
- 이때 사용하는 명령문을 제어문이라고 하며, 이러한 제어문에는 조건문, 반복문 등이 있다.
- 이러한 제어문에 속하는 명령문들은
{}
(중괄호)로 둘러싸여 있으며, 이러한 중괄호 영역을 블록이라고 한다.
2) 조건문(Conditional Statements)
- 조건문은 주어진 조건식의 결과에 따라 별도의 명령을 수행하도록 제어하는 명령문이다.
- 조건문 중에서도 가장 기본이 되는 명령문은 바로
if
문이다. - 자바에서 사용하는 대표적인 조건문의 형태는 다음과 같다.
1] if
문
2] if
/ else
문
3] if
/ else if
/ else
문
4] switch
문
(1) if
문
if
문은 조건식의 결과가 참이면 주어진 명령문을 실행하며, 거짓인면 아무것도 실행하지 않는다.
if
문을 순서도로 표현하면 다음 그림과 같다.
- 자바에서
if
문의 문법은 다음과 같다.
- 위의 코드에서 블록에 속한 명령문은 중괄호를 기준으로 오른쪽으로 들여쓰기가 되어 있는 것을 볼 수 있다.
- 이처럼 들여쓰기를 통해 코드의 가독성을 높이는 것을 인덴트(Indent)라고 하며, 모든 코드를 인덴트하는 것이 좋다.
- 다음 예제는
if
문을 사용하여, 해당 문자가 영문 소문자인지를 확인하는 예제이다.
(2) if
/ else
문
if
문과 함께 사용하는else
문은if
문과는 반대로 주어진 조건식의 결과가 거짓이면 주어진 명령문을 실행한다.
if
/else
문을 순서도로 표현하면 다음 그림과 같다.
- 자바에서
if
/else
문의 문법은 다음과 같다.
- 다음 예제는
if
/else
문을 사용하여, 해당 문자가 영문 소문자인지 아닌지를 확인하는 예제이다.
if (ch >= 'a' && ch <= 'z') {
System.out.println("해당 문자는 영문 소문자입니다.");
} else {
System.out.println("해당 문자는 영문 소문자가 아닙니다.");
}
// 해당 문자는 영문 소문자가 아닙니다.
(3) if
/ else if
/ else
문
if
/else if
/else
문은 마치 새로운 구문처럼 보이지만, 사실 두 개의if
/else
문이 연달아 나온 것 뿐이다.- 이러한
if
/else if
/else
문은 조건식을 여러 개 명시할 수 있으므로 중첩된if
문을 좀 더 간결하게 표현할 수 있다.
if
/else if
/else
문을 순서도로 표현하면 다음 그림과 같다.
- 자바에서
if
/else if
/else
문의 문법은 다음과 같다.
if (조건식1) {
조건식1의 결과가 참일 때 실행하고자 하는 명령문;
} else if (조건식2) {
조건식2의 결과가 거짓일 때 실행하고자 하는 명령문;
} else {
조건식1의 결과도 거짓이고, 조건식2의 결과도 거짓일 때 실행하고자 하는 명령문;
}
- 이때
else if
문은 여러 번 나와도 상관없지만,if
문과else
문은 단 한 번만 나올 수 있다.
- 다음 예제는
if
/else if
/else
문을 사용하여, 해당 문자가 영문 소문자나 영문 대문자인지, 아니면 영문자가 아닌지를 확인하는 예제이다.
if (ch >= 'a' && ch <= 'z') {
System.out.println("해당 문자는 영문 소문자입니다.");
} else if (ch >= 'A' && ch <= 'Z') {
System.out.println("해당 문자는 영문 대문자입니다.");
} else {
System.out.println("해당 문자는 영문자가 아닙니다.");
}
// 해당 문자는 영문 대문자입니다.
(4) 삼항 연산자에 의한 조건문
- 자바에서는 간단한
if
/else
문은 삼항 연산자를 이용하여 간결하게 표현할 수 있다.
(5) switch
문
switch
문은if
/else
문과 마찬가지로 주어진 조건 값의 결과에 따라 프로그램이 다른 명령을 수행하도록 하는 조건문이다.- 이러한
switch
문은if
/else
문보다 가독성이 더 좋으며, 컴파일러가 최적화를 쉽게 할 수 있어 속도 또한 빠른 편이다. - 하지만
switch
문의 조건 값으로는int
형으로 승격할 수 있는(Integer Promotion) 값만이 사용될 수 있다. - 즉, 자바에서는
switch
문의 조건 값으로byte
형,short
형,char
형,int
형의 변수나 리터럴을 사용할 수 있다. - 또한, 이러한 기본 타입에 해당하는 데이터를 객체로 포장해 주는 래퍼 클래스(Wrapper Class) 중에서 위에 해당하는
Byte
,Short
,Character
,Integer
클래스의 객체도 사용할 수 있다. - 그리고
enum
키워드를 사용한 열거체(Enumeration Type)와String
클래스의 객체도 사용할 수 있다. - 따라서
switch
문은if
/else
문보다는 사용할 수 있는 상황이 적다.
- 자바에서
switch
문의 문법은 다음과 같다.
switch (조건 값) {
case 값1:
조건 값이 값1일 때 실행하고자 하는 명령문;
break;
case 값2:
조건 값이 값1일 때 실행하고자 하는 명령문;
break;
...
default:
조건 값이 어떠한 case 절에도 해당하지 않을 때 실행하고자 하는 명령문;
break;
}
default
절은 조건 값이 위에 나열된 어떠한case
절에도 해당하지 않을 때만 실행된다.- 이 절은 반드시 존재해야 하는 것은 아니며 필요할 때만 선언할 수 있다.
- 다음 예제는
switch
문을 사용하여, 해당 문자가 영문자 모음인지를 확인하는 예제이다.
switch (ch) {
case 'a':
System.out.println("해당 문자는 'A'입니다.");
break;
case 'e':
System.out.println("해당 문자는 'E'입니다.");
break;
case 'i':
System.out.println("해당 문자는 'I'입니다.");
break;
case 'o':
System.out.println("해당 문자는 'O'입니다.");
break;
case 'u':
System.out.println("해당 문자는 'U'입니다.");
break;
default:
System.out.println("해당 문자는 모음이 아닙니다.");
break;
}
// 해당 문자는 'I'입니다.
default
절은 위의 예제와 같이 맨 마지막에 위치하는 것이 일반적이지만,case
절 사이에 위치해도 상관없다.- 각
case
절 및default
절은 반드시break
키워드를 포함하고 있어야 한다. break
키워드는 조건 값에 해당하는case
절이나default
절이 실행된 뒤에 전체switch
문을 빠져나가게 해준다.- 만약에
break
키워드가 없다면, 조건에 해당하는switch
문의case
절 이후의 모든case
절이 전부 실행될 것이다.
- 다음 예제는 앞서 살펴본 예제에서
break
키워드를 모두 삭제한 예제이다.
switch (ch) {
case 'a':
System.out.println("해당 문자는 'A'입니다.");
case 'e':
System.out.println("해당 문자는 'E'입니다.");
case 'i':
System.out.println("해당 문자는 'I'입니다.");
case 'o':
System.out.println("해당 문자는 'O'입니다.");
case 'u':
System.out.println("해당 문자는 'U'입니다.");
default:
System.out.println("해당 문자는 모음이 아닙니다.");
}
// 해당 문자는 'I'입니다.
// 해당 문자는 'O'입니다.
// 해당 문자는 'U'입니다.
// 해당 문자는 모음이 아닙니다.
- 위의 예제처럼
break
키워드가 없으면, 조건 값에 해당하는case
절뿐만 아니라 그 이후에 등장하는 모든case
절과default
절이 전부 실행된다.
- 다음 예제는 조건 값으로 여러 개의
char
형 문자를 확인하는 예제이다. - 이렇게
switch
문의 조건으로 여러 개의case
절을 사용하여 여러 개의 조건 값을 한 번에 검사할 수 있다.
switch (ch) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
System.out.println("해당 문자는 소문자 모음입니다.");
break;
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
System.out.println("해당 문자는 대문자 모음입니다.");
break;
default:
System.out.println("해당 문자는 모음이 아닙니다.");
break;
}
// 해당 문자는 대문자 모음입니다.
3. 반복문(Iteration Statements)
- 반복문이란 프로그램 내에서 똑같은 명령을 일정 횟수만큼 반복하여 수행하도록 제어하는 명령문이다.
- 프로그램이 처리하는 대부분의 코드는 반복적인 형태가 많으므로, 가장 많이 사용되는 제어문 중 하나이다.
- 자바에서 사용되는 대표적인 반복문의 형태는 다음과 같다.
1] while
문
2] do
/ while
문
3] for
문
4] Enhanced for
문
1) while
문
while
문은 특정 조건을 만족할 때까지 계속해서 주어진 명령문을 반복 실행한다.
- 자바에서
while
문의 문법은 다음과 같다.
while
문은 우선 조건식이 참인지를 판단하여, 참이면 내부의 명령문을 실행한다.- 내부의 명령문을 전부 실행하고 나면, 다시 조건식으로 돌아와 또 한 번 참인지를 판단하게 된다.
- 이렇게 조건식의 검사를 통해 반복해서 실행되는 반복문을 루프(Loop)라고 한다.
- 다음 예제는
while
문을5
번 반복해서 실행하는 예제이다.
int i = 0;
while (i < 5) {
System.out.println("while 문이 " + (i + 1) + "번째 반복 실행중입니다.");
i++;
}
System.out.println("while 문이 종료된 후 변수 i의 값은 " + i + "입니다.");
// while 문이 1번째 반복 실행중입니다.
// while 문이 2번째 반복 실행중입니다.
// while 문이 3번째 반복 실행중입니다.
// while 문이 4번째 반복 실행중입니다.
// while 문이 5번째 반복 실행중입니다.
// while 문이 종료된 후 변수 i의 값은 5입니다.
while
문 내부에 조건식의 결과를 변경하는 명령문이 존재하지 않을 때는 프로그램이 영원히 반복된다.- 이것을 무한 루프(Infinite Loop)에 빠졌다고 하며, 무한 루프에 빠진 프로그램은 영원히 종료되지 않는다.
- 무한 루프는 특별히 의도한 경우가 아니라면 반드시 피해야 하는 상황이다.
- 따라서
while
문을 작성할 때는 조건식의 결과가 어느 순간 거짓을 갖도록 조건식의 결과를 변경하는 명령문을 반드시 포함시켜야 한다. - 위의 예제에서 조건식의 결과를 변경하는 명령문인
i++
를 제거하면, 변수i
의 값은 언제나1
이기 때문에 무한 루프에 빠지게 된다.
2) do
/ while
문
while
문은 루프에 진입하기 전에 먼저 조건식부터 검사한다.- 하지만
do
/while
문은 먼저 루프를 한 번 실행한 후에 조건식을 검사한다. - 즉,
do
/while
문은 조건식의 결과와 상관없이 무조건 한 번은 루프를 실행한다.
- 자바에서
do
/while
문의 문법은 다음과 같다.
int i = 1, j = 1;
while (i < 1) {
System.out.println("while 문이 " + i + "번째 반복 실행중입니다.");
i++;
}
System.out.println("while 문이 종료된 후 변수 i의 값은 " + i + "입니다.");
do {
System.out.println("do / while 문이 " + i + "번째 반복 실행중입니다.");
j++;
} while (j < 1);
System.out.println(
"do / while 문이 종료된 후 변수 j의 값은 " + j + "입니다."
);
// while 문이 종료된 후 변수 i의 값은 1입니다.
// do / while 문이 1번째 반복 실행중입니다.
// do / while 문이 종료된 후 변수 j의 값은 2입니다.
- 위의 예제가 만약
while
문이었다면 단 한 번의 출력도 없었을 것이다. - 하지만
do
/while
문은 조건식의 결과와 상관없이 무조건 한 번은 루프를 실행해 준다.
3) for
문
for
문은while
문과는 달리 자체적으로 초기식, 조건식, 증감식을 모두 포함하고 있는 반복문이다.- 따라서
while
문보다는 좀 더 간결하게 반복문을 표현할 수 있다.
- 자바에서
for
문의 문법은 다음과 같다.
- 이때
for
문을 구성하는 초기식, 조건식, 증감식은 각각 생략할 수 있다. for
문을 사용하면 앞선 예제의while
문을 더욱 더 간결하게 표현할 수 있다.
int i;
for (i = 0; i < 5; i++) {
System.out.println("for 문이 " + (i + 1) + "번째 반복 실행중입니다.");
}
System.out.println("for 문이 종료된 후 변수 i의 값은 " + i + "입니다.");
}
// for 문이 1번째 반복 실행중입니다.
// for 문이 2번째 반복 실행중입니다.
// for 문이 3번째 반복 실행중입니다.
// for 문이 4번째 반복 실행중입니다.
// for 문이 5번째 반복 실행중입니다.
// for 문이 종료된 후 변수 i의 값은 5입니다.
- 자바에서는 다음 예제처럼
for
문 안에서만 사용하는 변수를 초기식에서 직접 선언할 수 있다. - 이렇게
for
문에서 직접 선언된 변수는for
문이 종료되면 같이 소멸한다.
for (int i = 0; i < 3; i++) {
System.out.println("for 문이 " + (i + 1) + "번째 반복 실행중입니다.");
}
① // System.out.println(i);
for (int i = 0; i < 3; i++) {
System.out.println("for 문이 " + (i + 1) + "번째 반복 실행중입니다.");
}
// for 문이 1번째 반복 실행중입니다.
// for 문이 2번째 반복 실행중입니다.
// for 문이 3번째 반복 실행중입니다.
// for 문이 1번째 반복 실행중입니다.
// for 문이 2번째 반복 실행중입니다.
// for 문이 3번째 반복 실행중입니다.
- 위의 예제에서 반복문을 종료시키기 위한 변수로
i
라는 이름의int
형 변수를 한 프로그램에서 두 번이나 선언하고 있다. - 하지만 이렇게 두 번이나 선언해도 컴파일 오류가 발생하지 않는 이유는
for
문이 종료되면for
문의 초기식에서 사용되는 변수는 자동으로 소멸하기 때문이다. - 따라서 ①번 라인에서 변수
i
를 참조하려고 하면 선언되지 않은 변수를 참조하려는 것이므로, 오류가 발생한다.
4) Enhanced for
문
- Enhanced
for
문은 컬렉션 프레임워크와 배열에서 유용하게 자주 사용된다.
4. 기타 제어문
- 일반적으로 조건식의 검사를 통해 루프로 진입하면, 다음 조건식을 검사하기 전까지 루프 안에 있는 모든 명령문을 실행한다.
- 하지만
continue
문과break
문은 이러한 일반적인 루프의 흐름을 사용자가 직접 제어할 수 있도록 도와준다.
1) continue
문
continue
문은 루프 내에서 사용하여 해당 루프의 나머지 부분을 건너뛰고, 바로 다음 조건식의 판단으로 넘어가게 해준다.- 보통 반복문 내에서 특정 조건에 대한 예외 처리를 하고자 할 때 자주 사용된다.
- 다음 예제는
1
부터100
까지의 정수 중에서5
의 배수와7
의 배수를 모두 출력하는 예제이다.
for (int i = 1; i <= 100; i++) {
if (i % 5 == 0 || i % 7 == 0) {
System.out.println(i);
} else {
continue;
}
}
// 5
// 7
// 10
// ...
// 95
// 98
// 100
2) break
문
break
문은 루프 내에서 사용하여 해당 반복문을 완전히 종료시킨 뒤, 반복문 바로 다음에 위치한 명령문을 실행한다.- 즉, 루프 내에서 조건식의 판단 결과와 상관없이 반복문을 완전히 빠져나가고 싶을 때 사용한다.
- 다음 예제는
1
부터100
까지의 합을 무한 루프를 통해 구하는 예제이다.
int num = 1, sum = 0;
while (true) {
sum += num;
if (num == 100) {
break;
}
num++;
}
System.out.println(sum); // 5050
3) 이름을 가지는 반복문(Break with Label)
- 일반적인
break
문은 단 하나의 반복문만을 빠져나가게 해준다. - 따라서 여러 반복문이 중첩된 상황에서 한 번에 모든 반복문을 빠져나가거나, 특정 반복문까지만 빠져나가고 싶을 때는 다른 방법을 사용해야 한다.
- 이때 사용할 수 있는 방법이 바로 반복문에 이름(Label)을 설정하는 것이다.
- 가장 바깥쪽 반복문이나 빠져나가고 싶은 특정 반복문에 이름을 설정한 후,
break
키워드 다음에 해당 이름을 명시하면 된다. - 그러면 해당
break
키워드는 현재 반복문이 아닌 해당 이름의 반복문 바로 다음으로 프로그램의 실행을 옮겨준다. - 단, 이때 이름(Label)은 가리키고자 하는 반복문의 키워드 바로 앞에 위치해야 한다.
- 이름과 반복문의 키워드 사이에 명령문이 존재하면, 자바 컴파일러는 오류를 발생시킬 것이다.
- 다음 예제는 구구단 중에서 2단부터 4단까지를 출력하는 예제이다.
allLoop:for (int i = 2; i < 10; i++) {
for (int j = 2; j < 10; j++) {
if (i == 5) {
break allLoop;
}
System.out.println(i + " * " + j + " = " + (i * j));
}
}
// 2 * 2 = 4
// 2 * 3 = 6
// 2 * 4 = 8
// ...
// 4 * 7 = 28
// 4 * 8 = 32
// 4 * 9 = 36
- 위의 예제에서 변수
i
의 값이5
가 되는 순간, 해당 프로그램의 제어는 두 개의for
문을 모두 빠져나와 종료된다.