[자바의 정석] 04. 조건문과 반복문
1. 조건문 - if, switch
프로그램의 흐름(flow)를 바꾸는 역할을 하는 문장들을 ‘제어문(controlstatement)’이라고 한다.
제어문에는 ‘조건문과 반목문’이 있는데, 조건문은 조건에 따라 다른 문장이 수행되도록 하고, 반복문은 특정 문장들을 반복해서 수행한다.
1.1 if문
if문은 가장 기본적인 조건문
만일(if) 조건식이 참(true)이면 괄호{} 안의 문장들을 수행하라.
if (조건식) {
//조건식이 참(true) 일 때 수행될 문장들을 적는다.
}
//조건식이 거짓(false)이면, if문 다음의 문장으로 넘어간다.
조건식
if문에 사용되는 조건식은 일반적으로 비교연산자와 논리연산자로 구성된다.
[자주 사용되는 조건식]
조건식 | 조건식이 참일 조건 |
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’일 때 |
ch == ‘ ‘ || ch == ‘\t’ || ch == ‘\n’ | 문자 ch가 공백이거나 탭 또는 개행 문자일 때 |
‘A’ <= ch && ch <= ‘Z’ | 문자 ch가 대문자일 때 |
'a’ <= ch && ch <= ‘z’ | 문자 ch가 소문자일 때 |
'0’ <= ch && ch <= ‘9’ | 문자 ch가 숫자일 때 |
str.equals(”yes”) | 문자열 str의 내용이 “yes”일 때(대소문자 구분) |
str.equalsIgnoreCase(”yes”) | 문자열 str의 내용이 “yes”일 때(대소문자 구분 안 함) |
자바에서 조건식의 결과는 반드시 true 또는 false이어야 한다는 것을 잊지 말자.
블럭{ }
괄호 {}를 이용해서 여러 문장을 하나의 단위로 묶을 수 있는데, 이것을 ‘블럭(block)’이라고 한다.
1.2 if-else문
if문의 변형인 if-else문의 구조는 다음과 같다. if문에 ‘else블럭’이 더 추가되었다.
조건식의 결과가 참이 아닐 때, 즉 거짓일 때 else블럭의 문장을 수행하라는 뜻이다.
if (조건식) {
// 조건식이 참(true)일 때 수행될 문장들을 적는다.
} else {
// 조건식이 거짓(false)일 땓 수행될 문장들을 적는다.
}
조건식의 결과에 따라 이 두 개의 블럭{} 중 어느 한 블럭{}의 내용이 수행되고 전체 if문을 벗어나게 된다.
1.3 if-else if문
처리해야할 경우의 수가 셋 이상인 경우
한 문장에 여러 개의 조건식을 쓸 수 있는 ‘if-else if’문을 사용하면 된다.
if (조건식1) {
// 조건식1의 연산결과가 참일 때 수행될 문장들을 적는다.
} else if (조건식2) {
// 조건식2이 연산결과가 참일 땓 수행될 문장들을 적는다.
} else if (조건식3) { //여러 개의 else if를 사용할 수 있다.
// 조건식3이 연산결과가 참일 땓 수행될 문장들을 적는다.
} else { // 마지막에는 보통 else블럭으로 끝나며, else블럭은 생략가능하다.
// 위의 어느 조건식도 만족하지 않을 때 수행될 문장들을 적는다.
}
첫 번째 조건식부터 순서대로 평가해서 결과가 참인 조건식을 만나면, 해당 블럭{}만 수행하고 ‘if-else if’문 전체를 벗어난다.
else블럭이 생략되었을 때는 if-else if’문의 어떤 블럭도 수행되지 않을 수 있다.
1.4 중첩 if문
if문의 블럭 내에 또 다른 if문을 포함시키는 것이 가능한데 이것을 중첩 if문이라고 부르며 중첩의 횟수에는 거의 제한이 없다.
if (조건식1) {
// 조건식1의 연산결과가 true일 때 수행될 문장들을 적는다.
if (조건식2) {
// 조건식1과 조건식2가 모두 true일 때 수행될 문장들
} else {
// 조건식1이 true이고, 조건식1가 false일 때 수행되는 문장들
}
} else {
// 조건식 1이 false일 때 수행되는 문장들
}
1.5 switch문
switch문은 단 하나의 조건식으로 많은 경우의 수를 처리할 수 있고, 표현도 간결하므로 알아보기 쉽다.
그래서 처리할 경우의 수가 많은 경우에는 if문 보다 switch문으로 작성하는 것이 좋다.
다만 switch문은 제약조건이 있다.
switch문은 조건식을 먼저 계산한 다음, 그 결과와 일치하는 case문으로 이동한다.
- 조건식을 계산한다.
- 조건식의 결과와 일치하는 case문으로 이동한다.
- 이후의 문장들을 수행한다.
- break문이나 switch문의 끝을 만나면 switch문 전체를 빠져나간다.
switch (조건식) {
case 값1 :
// 조건식의 결과가 값1과 같을 경우 수행될 문장들
// ...
break;
case 값2 :
// 조건식의 결과가 값2와 같을 경우 수행될 문장들
// ...
break; //switch문을 벗어난다.
// ...
default :
// 조건식의 결과와 일치하는 case문이 없을 때 수행될 문장들
//...
}
만일 조건식의 결과와 일치하는 case문이 하나도 없는 경우에는 default문으로 이동한다.(else같은)
switch문에서 break문은 각 case문의 영역을 구분하는 역할을 하는데,
만일 break문을 생략하면 case문 사이의 구분값이 없어지므로 다른 break문을 만나거나 switch문 블럭{}의 끝을 만날 때까지 나오는 모든 문장들을 수행한다.
고의적으로 break문을 생략하는 경우도 있다.
switch문의 제약조건
switch문의 조건식은 결과값이 반드시 정수이어야 하며,
이 값과 일치하는 case문으로 이동하기 때문에 case문의 값 역시 정수이어야 한다.
그리고 중복되지 않아야 한다.
같은 값의 case문이 여러 개이면, 어디로 이동해야할 지 알 수 없기 때문이다
switch문의 제약조건
- switch문의 조건식 결과는 정수 또는 문자열이어야 한다.
- case문의 값은 정수 상수만 가능하며, 중복되지 않아야 한다. (변수나 상수, 문자열은 case문의 값으로 사용할 수 없다.)
❓JDK1.7이전에는 switch문의 조건식에 문자열이 허용되지 않았다.
if문처럼 switch문도 중첩이 가능하다.
한 가지 주의할 점은 중첩 switch문에서 break문을 빼먹기 쉽다는 것이다.
2. 반복문 - for, while, do-while
반복문은 어떤 작업이 반복적으로 수행되도록 할 때 사용된다.
for문이나 while문에 속한 문장은 조건에 따라 한 번도 수행되지 않을 수 있지만 do-while문에 속한 문장은 무조건 최소한 한 번은 수행될 것이 보장된다.
반복문은 주어진 조건을 만족하는 동안 주어진 문장들을 반복적으로 수행하므로 조건식을 포함한다.
if문과 마찬가지로 조건식의 결과가 true이면 참이고, false면 거짓으로 간주된다.
for문과 while문은 구조와 기능이 유사.
2.1 for문
for문은 반복 횟수를 알고 있을 때 적합하다.
아래의 for문은 블럭{} 내의 문장을 5번 반복한다.
for(int i=1; i<=5; i++) {
System.out.println("Hello");
} //1부터 5까지 1씩 증가
변수 i에 1을 저장한 다음, 매 반복바다 i의 값을 1씩 증가시킨다.
그러다가 i의 값이 5를 넘으면 조건식 ‘i<=5’가 거짓이 되어 반복을 마치게 된다
for문의 구조와 수행순서
for문은 아래와 같이 ‘초기화’, ‘조건식’, ‘증감식’, ‘블럭{}’, 모두 4부분으로 이루어져 있다.
for (초기화; 조건식; 증감식) {
//조건식이 참일 때 수행될 문장들을 적는다.
}
초기화
처음에 한번만 수행된다.
둘 이상의 변수가 필요할 때는 아래와 같이 콤마’,’를 구분자로 변수를 초기화하면 된다. 두 변수의 타입은 같아야 한다.
for ( int i=1; i<=10; i++ ) { … } // 변수 i의 값을 1로 초기화 한다.
for( int i=1, j=0; i<=10; i++ ) { … } // int타입의 변수 i와 j를 선언하고 초기화
조건식
조건식의 값이 참(true)이면 반복을 계속하고, 거짓(false)이면 반복을 중단하고 for문을 벗어난다.
for ( int i=1; i<=10; i++ ) { … } // ‘i <= 10’가 참인 동안 블럭{} 안의 문장들을 반복
증감식
반복문을 제어하는 변수의 값을 증가 또는 감소시키는 식이다.
매 반복마다 변수의 값이 증감식에 의해서 점진적으로 변하다가 결국 조건식이 거짓이 되어 for문을 벗어나게 된다.
for ( int i=1; i<=10; i++ ) { … } // 1부터 10까지 1씩 증가
for ( int i=10; i<=1; i+- - ) { … } // 10부터 1까지 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씩 감소한다.
이 세 가지 요소는 필요하지 않으면 생략할 수 있다.
for(;;) {…} //조건식은 참이 된다.
무한 반복문이 된다. {}안에 if문을 넣어서 특정 조건을 만족하면 for문을 빠져나오게 해야 한다.
중첩 for문
for문 안에 또 다른 for문을 포함시키는 것
중첩의 횟수는 거의 제한이 없다.
for(int i=1;i<=5;i++) {
for(int j=1;j<=i;j++) {
System.out.print("*");
}
System.out.println();
}
//바깥 쪽 for문이 5번(↓밑으로) 안쪽 for문이 i개수 대로(1~5)
향상된 for문(enhanced for statement)
JDK1.5 부터 for문의 새로운 문법이 추가됨
for ( 타입 변수명 : 배열 또는 컬렉션 ) {
// 반복할 문장
}
위 문장에서 타입은 배열 또는 컬렉션의 요소의 타입이어야 한다.
배열 또는 컬렉션에 저장된 값이 매 반복마다 하나씩 순서대로 읽혀서 변수에 저장된다. 그리고 반복문의 괄호 {} 내에서는 이 변수를 사용해서 코드를 작성한다.
int[] arr = {10,20,30,40,50};
배열 arr을 위와 같인 선언했을 때, 이 배열의 모든 요소를 출력하는 for문은 아래와 같다.
for(int i=0; i<arr.length; i++) {
System.out.println(arr[i]);
}
↓
for(int tmp : arr) {
System.out.println(tmp);
}
향상된 for문은 일반적인 for문과 달리 배열이나 컬렉션에 저장된 요소들을 읽어오는 용도로만 사용할 수 있다는 제약이 있다.
2.2 while문
if문 처럼 조건식과 블럭{}만으로 이러우져 있다. 다만 if문과 달리
while문은 조건식이 ‘참(true)’인 동안’, 즉 조건식이 거짓이 될 때까지 블럭{} 내의 문장을 반복한다.
- 조건식이 참(true)이면 블럭{}안으로 들어가고, 거짓(false)이면 while문을 벗어난다.
- 블럭{}의 문장을 수행하고 다시 조건식으로 돌아간다.
한 가지 주의할 점은 for문과 달리 while문의 조건식은 생략할 수 없다는 것이다.
그래서 while문의 조건식이 항상 참이 되도록 하려면 반드시 true를 넣어야 한다.(무한 반복)
int i=1; // 초기화
while(i<=10) { // 조건식
System.out.println(i);
i++; // 증감식
}
2.3 do-while문
do-while문은 while문의 변형으로 기본적인 구조는 while문과 같으나 조건식과 블럭{}의 순서를 바꿔놓은 것이다. 그래서 while문과 반대로 블럭{}을 먼저 수행한 후에 조건식을 평가한다.
do-while문은 최소한 한번은 수행될 것을 보장한다.(사용자가 입력받을 때 유용)
do {
// 조건식의 연산결과가 참일 때 수행될 문장들을 적는다.
} while (조건식); <-끝에 ';'을 잊지 않도록 주의
2.4 break문
반복문에서도 break문을 사용할 수 있다.
switch문 처럼 break문은 자신이 포함된 가장 가까운 반복문을 벗어난다.
무한반복문에는 조건문과 break문이 항상 같이 사용된다.
2.5 continue문
continue문은 반복문 내에서만 사용될 수 있으며, 반복이 진행되는 도중에 continue문을 만나면 반복문의 끝으로 이동하여 다음 반복문으로 넘어간다.
fot문의 경우 증감식으로 이동하며, while문과 do-while문의 경우 조건식으로 이동한다.
continue문은 반복문 전체를 벗어나지 않고 다음 반복을 계속 수행한다는 점이 break문과 다르다.
주로 if문과 함께 사용되어 특정 조건을 만족하는 경우에 continue문 이후의 문장들을 수행하지 않고 다음 반복으로 넘어가서 계속 진행하도록 한다.
전체 반복 중에 특정조건을 만족하는 경우를 제외하고자 할 때 유용하다.
class Ex4_17 {
public static void main(String[] args) {
for(int i=0;i <= 10;i++) {
if (i%3==0)
continue;
System.out.println(i);
}
}
}
▼실행결과
1
2
4
5
7
8
10
//1과 10 사이의 숫자를 출력하되 그 중에서 3의 배수인 것은 제외하도록 하였다.
2.6 이름 붙은 반복문
break 문은 근접한 단 하나의 반복문을 벗어난다.
중첩 반복문 앞에 이름을 붙이고 break문과 continue문에 이름을 지정해 줌으로써 하나 이상의 반복문을 벗어나거나 반복을 건너뛸 수 있다.
출처 : 남궁성. 「자바의 정석」. 도우출판. 2016