** 단순히 공부를 위한 참고자료일 뿐입니다. **
** 현재 버전과 상이한 부분은 검색해주시길 바랍니다. **
1. 조건문 - if, switch
조건문은 조건식과 문장을 포함하는 블럭{}으로 구성되어 있으며, 조건식의 연산결과에 따라
실행될 문장을 달리 할 수 있다.
처리해야할 경우의 수가 많을 때는 switch문을 사용해서 표현할 수 있는지 살펴봐야 한다.
[참고] 모든 switch문은 if문으로 변경이 가능하지만, 모든 if문이 switch문으로 변경 가능한
것은 아니다.
1.1 if문
if문은 널리 사용되는 조건문이며, 기본구조는 다음과 같다.
if (조건식) {
// 조건식의 연산결과가 true일 때 수행될 문장들을 적는다.
}
if 다음에 오는 조건식에는 연산의 최종결과 값이 true 또는 false인 수식만을 사용할 수 있다. 조건식의 결과가 false이면, 블럭{} 내의 문장이 실행되지 않는다.
[참고] C언어에서는 조건식의 최종결과 값으로 true 또는 false 이외의 값을 허용하지만, 자바 에서는 이를 허용하지 않는다.
if 문의 변형인 if-else문의 기본 구조는 다음과 같다. if문에 else블럭을 추가한 것이다. else블 럭 내의 문장들은 if문의 조건식의 결과가 false일 때 수행되는 문장들이다. 조건식의 결과에 따라 이 두 개의 블럭 중 어느 한 블럭의 내용만 수행하고 전체 if문을 벗어나게 된다.
if (조건식) {
// 조건식의 연산결과가 true일 때 수행될 문장들을 적는다.
} else {
// 조건식의 연산결과가 false일 때 수행될 문장들을 적는다.
}
if문의 또 다른 변형으로 if-else if가 있는데 기본 구조는 다음과 같다. 여러 개의 블럭 중 조건
식을 만족하는 하나의 블럭만을 수행하고 if문 전체를 빠져나가게 된다.
if-else if의 기본구조는 다음과 같다.
if (조건식1) {
// 조건식1의 연산결과가 true일 때 수행될 문장들을 적는다.
} else if (조건식2) {
// 조건식2의 연산결과가 true일 때 수행될 문장들을 적는다.
} else if (조건식3) { // 여러 개의 else if를 사용할 수 있다. // 조건식3의 연산결과가 true일 때 수행될 문장들을 적는다. //...
} else { // 보통 else블럭으로 끝나며, else블럭은 생략이 가능하다. // 위의 어느 조건식도 만족하지 않을 때 수행될 문장들을 적는다.
}
블럭{}은 여러 개의 문장을 하나로 묶기 위해 사용되는 것이며, 함수, 조건문, 반복문 등에 사용
된다. 조건문과 반복문에서는 수행될 문장이 하나인 경우 블럭을 생략할 수 있으나, 가능하면
생략 않고 사용하는 것이 바람직하다.
수 행될 문장이 한 문장이라서 블럭을 생략하고 적었을 때, 나중에 새로운 문장들이 추가되면
블럭으로 문장들을 감싸 주어야 하는데 이 때 블럭을 추가하는 것을 잊기 쉽기 때문이다. 그리
고, 여러 개의 if문이 중첩되어 사용되었을 때 if문과 else블럭의 관계가 의도한 바와 다르게 형
성될 수도 있다.
[예제4-1] FlowEx1.java
class FlowEx1 { public static void main(String[] args) { int visitCount = 0; if (visitCount < 1) { System.out.println("처음 오셨군요. 방문해 주셔서 감사합니다.") ; } } } |
[실행결과] |
처음 오셨군요. 방문해 주셔서 감사합니다. |
[예제4-2] FlowEx2.java |
class FlowEx2 { public static void main(String[] args) { int visitCount = 5; System.out.println("처음 오셨군요. 방문해 주셔서 감사합니다.") ; } else { System.out.println("다시 방문해 주셔서 감사합니다.") ; } System.out.println("방문횟수는 " + ++visitCount + "번 입니다."); } } |
[실행결과] |
다시 방문해 주셔서 감사합니다. 방문횟수는 6번 입니다. |
예제4-3] FlowEx3.java
class FlowEx3 { public static void main(String[] args) { } int score = 45; if (score >= 90) { grade = 'A'; } else { grade = 'B'; grade = 'C'; // score가 90점 보다 같거나 크면 A학점(grade) // score가 80점 보다 같거나 크면 B학점(grade) // 나머지는 C학점(grade) System.out.println("당신의 학점은 " + grade + "입니다."); } } |
[실행결과] |
당신의 학점은 C입니다. |
if문은 삼항연산자(? :)로 바꿀 수 있는 경우가 많이 있는데, 간단한 if문의 경우 삼항연산자를
사용한 문장들로 변경하는 것을 고려해보도록 한다.
위의 예제에서 if문 대신 삼항연산자를 사용하면 다음과 같다.
[예제4-4] FlowEx4.java |
class FlowEx4 { public static void main(String[] args) { int score = 45; |
char grade ='\u0000'; System.out.println("당신의 학점은 " + grade + "입니다."); } } |
[실행결과] |
당신의 학점은 C입니다. |
두 예제는 모두 같은 결과를 얻지만, 삼항연산자를 사용한 두 번째 예제가 보다 더 간결하다. 이렇듯 삼항연산자를 활용하면, if문을 간단히 표현할 수 있다.
1.2 중첩 if문
if문의 블럭 내에 또 다른 if문을 사용하는 것이 가능하며, 이것을 중첩 if문이라고 부른다.
if (조건식1) {
// 조건식1의 연산결과가 true일 때 수행될 문장들을 적는다.
if (조건식2) {
// 조건식1과 조건식2가 모두 true일 때 수행될 문장들 } else {
// 조건식1이 true이고, 조건식2가 false일 때 수행되는 문장들 }
} else {
// 조건식1이 false일 때 수행되는 문장들
}
[예제4-5] FlowEx5.java |
class FlowEx5 |
{ int score = 82; System.out.println("당신의 점수는 " + score + "입니다."); grade = "A"; grade += "+"; // grade = grade + "+";와 같다. } else if ( score < 94) { grade += "-"; } } else if (score >= 80){ // score가 80점 보다 같거나 크면 B학점(grade) grade = "B"; if ( score >= 88) { grade += "+"; } else if ( score < 84) { grade += "-"; } // 나머지는 C학점(grade) grade = "C"; } else { } System.out.println("당신의 학점은 " + grade + "입니다."); } } |
[실행결과] |
당신의 점수는 82입니다. 당신의 학점은 B-입니다. |
위 예제에서 보듯이, 모두 3개의 if문으로 이루어져 있으며 if문 내의 블럭에 또 다른 2개의 if문
을 포함하고 있는 모습을 하고 있다. 제일 바깥쪽에 있는 if문에서 점수에 따라 학점(grade)을 결정하고, 내부의 if문에서는 학점을 더 세부적으로 나누어서 평가를 하고 그 결과를 출력한다.
1.3 switch문
조 건의 경우의 수가 많을 때는 if문 보다 switch문을 사용하는 것이 더 간결하고 알아보기 쉽 다. if문은 조건식의 결과가 true, false 두 가지 밖에 없기 때문에 경우의 수가 많아 질수록 계 속 else-if를 추가해야하므로 조건식이 많아져서 복잡해지고, 여러 개의 조건식을 계산해야하 므로 수행시간도 많이 걸린다. 하지만, switch문의 조건식은 결과값으로 int형 범위의 정수값 을 허용하므로, 하나의 조건식만 계산하면 그 결과에 따라서 해당 문장들을 수행하면 되므로 같은 기능의 if문보다 속도가 빠르다.
하지만, switch문은 if문 보다 제약조건이 많기 때문에, 조건식을 switch문으로 작성할 수 없 는 경우가 많다.
switch문의 기본구조는 아래와 같다.
switch (조건식) { case 값1 :
// 조건식의 결과가 값1과 같을 경우 수행될 문장들
//...
break;
case 값2 :
// 조건식의 결과가 값2와 같을 경우 수행될 문장들
break;
//...
//... default :
// 조건식의 결과와 일치하는 case문이 없을 때 수행될 문장들
//... }
switch 문의 조건식은 연산결과가 int형 범위의 정수값이어야한다. byte, short, char, int 타
입의 변수나 리터럴을 사용할 수 있다. 그리고, case문에는 반드시 상수값만을 허용한다. 변수
는 허용되지 않으므로 유의해야한다.
switch문의 조건식을 먼저 계산한 다음, 그 결과와 일치하는 case문으로 이동하다. 이동한
case문 이하에 있는 문장들을 수행하며, break문을 만나면 전체 switch문을 빠져나가게 된다.
만일 case문 아래에 break문을 생략하면, 다른 break문을 만나거나 switch문 블럭의 끝을 만
날 때까지 나오는 모든 문장들을 수행한다.
[예제4-6] FlowEx6.java |
class FlowEx6 { public static void main(String[] args) { // Math클래스의 random()함수를 이용해서 1~10사이의 수를 임의로 얻어낼 수 있다. 다."); int score = (int)(Math.random() * 10) + 1; switch(score*100) { case 100 : System.out.println("당신의 점수는 100이고, 상품은 자전거입니다."); break; case 200 : System.out.println("당신의 점수는 200이고, 상품은 TV입니다."); break; case 300 : System.out.println("당신의 점수는 300이고, 상품은 노트북 컴퓨터입니 break; case 400 : break; |
default : 다."); } } |
[실행결과] |
당신의 점수는 100이고, 상품은 자전거입니다. |
Math클래스의 random메서드를 사용해서 1과 10사이의 임의의 수를 얻은 다음, 그 값을
score에 저장한다. score에 100을 곱한 값과 일치 하는 case문을 찾아서 이동한다.
예 를 들어서 score값이 1이라면, score * 100의 결과는 100이 되고, 첫 번째 case문인 case
100:으로 이동하여 System.out.println("당신의 점수는 100이고, 상품은 자전거입니다.")문
장을 수행한 후, break문을 만나서 switch문을 빠져 나오게 된다.
이 예제에서는 switch문의 조건식인 score * 100의 결과가, 100, 200, 300, 400인 경우에
대해서만 다루고 있기 때문에 그 외의 값인 500, 600, 700, 800, 900, 1000의 경우에는
default문 이하의 문장들 수행된다.
[참고]random메서드를 사용했기 때문에 매번 수행할 때마다 다른 결과를 얻게 될 것이다.
random메서드는 0.0과 1.0사이의 값 중 하나의 double값을 생성한다.(0.0은 범위에 포함되 고 1.0은 포함되지 않는다.)
예를 들어 1 과 10 사이의 정수를 구하기를 원한다면 아래와 같은 순서를 따르도록 한다. 1. 각 변에 10을 곱한다.
0.0 <= Math.random() < 1.0
0.0 * 10 <= Math.random() * 10 < 1.0 * 10 0.0 <= Math.random() * 10 < 10.0
2. 각 변을 int형으로 변환한다.
(int)0.0 <= (int)(Math.random() * 10) < (int)10.0 0 <= (int)(Math.random() * 10) < 10
지금까지는 0과 9사이의 정수 중 하나를 가질 수 있다.(0은 포함, 10은 포함 안됨) 3. 각 변에 1을 더한다.
0+1 <= (int)(Math.random() * 10) +1 < 10 +1 1 <= (int)(Math.random() * 10) +1 < 11
자, 이제는 1과 10사이의 정수 중 하나를 얻을 수 있다.(1은 포함, 11은 포함 안됨) [참고]순서 2와 3을 바꿔서, 각 변에 1을 먼저 더한 다음 int형으로 변환해도 같은 결과를 얻는 다.
위와 같은 방식으로 식을 변환해가며 범위를 조절하면 원하는 범위의 값을 얻을 수 있다. 주사 위를 던졌을 때 나타나는 임의의 값을 얻기 위해서는 10대신 6을 곱하면 된다. 그렇게 하면 1 과 6사이의 값을 얻어낼 수 있을 것이다.
random메서드의 활용 예를 한가지 더 소개하자면, 숫자 대신 임의의 문자를 얻을 수 있도록 하는 것이다. 대문자 A~Z사이의 문자 중 임의의 한 문자를 얻도록 하려면 다음과 같이 한다. [참고]대문자 26개의 코드값은 65부터 90까지(A~Z)이다.
0.0 <= Math.random() < 1.0
1. 발생시키려는 수의 개수가 26개 이므로 각 변에 26을 곱한다.
0.0 * 26 <= Math.random() * 26 < 1.0 * 26 0.0 <= Math.random() * 26 < 26.0
2. 65부터 시작하므로 각 변에 65를 더한다.
3. 각 변을 문자형(char형)으로 형변환을 한다.
65.0 <= Math.random() * 26 + 65 < 91.0
(char)65.0 <= (char)(Math.random() * 26 +65) < (char)91.0 'A' <= (char)(Math.random() * 26 +65) < '['
[참고] '['는 대문자 Z다음에 오는 문자.(코드값이 Z보다 1이 더 큰 문자).
여 기서 주의해야할 것은 위의 예에서와는 달리 char형으로 형변환한 후에 65를 더하면 전체 결과가 int형이 되어 버리기 때문에 char형 값을 얻을 수 없다. 그렇기 때문에 65를 먼저 더하 고 그 다음에 형변환을 해야 하는 것이다.
[예제4-7] FlowEx7.java |
class FlowEx7 { public static void main(String[] args) { |
char ch = (char)(Math.random() * 4 +65); // A, B, C, D중의 하나를 얻을 수 있 다. int score = 0; switch (ch) { case 'A': break; case 'B': score = 80; break; case 'C': score = 70; break; case 'D': score = 60; break; } System.out.println("당신의 점수는 "+ score +"점 이상 입니다."); } } |
[실행결과] |
당신의 점수는 80점 이상 입니다. |
[참고]Math.random()를 사용했기 때문에 실행결과가 이와 다를 수 있다.
[예제4-8] FlowEx8.java |
class FlowEx8 { public static void main(String[] args) { |
int score = 1; switch(score*100) { case 100 : System.out.println("당신의 점수는 100이고, 상품은 자전거입니다."); case 200 : case 300 : 다."); System.out.println("당신의 점수는 400이고, 상품은 자동차입니다."); default : 다."); } } |
[실행결과] |
당신의 점수는 100이고, 상품은 자전거입니다. |
위의 예제는 FlowEx6.java를 변형한 것으로 score의 값을 1로 고정시키고, switch문에 있는
break문을 모두 뺀 것이다.
score 의 값이 1이므로 switch문의 조건식 결과 값은 100이 된다. 그래서 case 100:으로 이
동한 후 그 이하의 문장들을 수행한다. FlowEx6.java과는 달리, break문이 없으므로 case
100:이후부터 switch문의 블럭 끝까지 모든 문장들을 수행하게 된다.
그렇기 때문에 매 case문마다 break문을 사용하는 것을 잊지 않도록 한다. 때로는 switch문의
이러한 성질을 이용하기도 한다.
[예제4-9] FlowEx9.java |
class FlowEx9 { public static void main(String[] args) { int score = (int)(Math.random() * 10) + 1; String msg =""; score *= 100; // score = score * 100; msg = "당신의 점수는 " + score + "이고, 상품은 "; switch(score) { case 1000 : msg += "자전거, "; case 900 : msg += "TV, "; case 800 : msg += "노트북 컴퓨터, "; case 700 : msg += "자전거, "; default : msg += "볼펜"; } // msg = msg + "자전거, "; System.out.println( msg + "입니다."); } } |
[실행결과] |
당신의 점수는 800이고, 상품은 노트북 컴퓨터, 자전거, 볼펜입니다. |
Math 클래스의 random()을 사용했기 때문에 위 예제의 결과는 실행할 때마다 결과가 다를 것이다. 위의 결과는 점수가 800점이 되었을 때의 결과이다. 점수(score)는 100부터 1000점 까지 100점 단위의 값을 갖을 수 있는데, 높은 점수를 얻을수록 많은 상품을 주도록 되어 있다. 예를 들어 1000점을 얻은 사람은 모든 상품을 다 가질 수 있도록 되어 있다.
이 예제에서 알 수 있듯이 switch문에 각 case문마다 반드시 break문을 사용해야하는 것은 아 니며, 이 성질을 잘 이용하면 보다 간결하고 논리적으로 명확한 코드를 작성할 수 있게 된다.
한 가지 더 간단한 예를 들어 보겠다. 아래의 코드는 전체 코드가 아닌 코드의 일부를 발췌한 것
인데,
회원제로 운영되는 인터넷 사이트에서 많이 사용될 만한 코드이다.
switch (level) { case 3 :
grantDelete(); case 2 :
grantWrite(); case 1 :
grantRead();
// 삭제권한을 준다. // 쓰기권한을 준다.
// 읽기권한을 준다.
}
로 그인한 사용자의 등급(level)을 체크하여, 등급에 맞는 권한을 부여하는 방식으로 되어 있 다. 제일 높은 등급인 3을 가진 사용자는 grantDelete, grantWrite, grantRead메서드가 모 두 수행되어 읽기, 쓰기, 삭제 기능까지 모두 갖게 되고, 제일 낮은 등급인 1을 가진 사용자는 읽기 권한만을 갖게 된다.
[참고]위의 코드는 사용자에게 읽기, 쓰기, 삭제권한을 주는 기능의 grantRead(), grantWrite(), grantDelete()가 존재한다는 가정 하에 작성되었다.
[예제4-10] FlowEx10.java |
class FlowEx10 { public static void main(String[] args) |
} { } char grade ='\u0000'; switch(score) { case 100: case 99: case 98: case 97: case 96: case 95: case 94: case 93: case 92: case 91: case 90 : grade = 'A'; break; grade = 'B'; break; grade = 'C'; break; grade = 'D'; break; default : grade = 'F'; } // end of switch System.out.println("당신의 학점은 " + grade + "입니다."); // end of main // end of class |
[실행결과] |
당신의 학점은 B입니다. |
위 의 예제는 예제4-3을 switch문을 이용해서 변형한 예제이다. 위의 예제를 if문을 이용해서
구현하려면, 조건식이 4개가 필요하며, 최대 4번의 조건식을 계산해야한다. 하지만, switch문 은 조건식을 1번만 계산하면 되므로 더 빠르다. 하지만, case문이 너무 많아지므로 좋지 않다.
반드시 속도를 더 향상시켜야 한다면 복잡하더라도 switch문을 선택해야겠지만, 그렇지 않다 면 이런 경우 if문이 더 적합하다.
[예제4-11] FlowEx11.java |
class FlowEx11 { public static void main(String[] args) { int score = 88; case 10: case 9 : grade = 'A'; break; case 8 : grade = 'B'; break; case 7 : grade = 'C'; break; case 6 : grade = 'D'; break; default : grade = 'F'; } System.out.println("당신의 학점은 " + grade + "입니다."); } } |
[실행결과] |
당신의 학점은 B입니다
이전 예제에 기교를 부려서 보다 간결하게 작성한 예제이다. score를 10으로 나누면, 전에 배 운 것과 같이 int / int의 결과는 int이기 때문에, 예를 들어 88/10은 8.8이 아니라 8을 얻는다. 따라서 80과 89사이의 숫자들은 10으로 나누면 결과가 8이 된다. 마찬가지로 70~79사이의 숫자들은 10으로 나누면 7이 된다.
'Programming' 카테고리의 다른 글
[Java의 정석] 제 5장 배열 (0) | 2017.06.26 |
---|---|
[Java의 정석] 제 4장 조건문과 반복문 - 2.반복문 (0) | 2017.06.26 |
[Java의 정석] 제 3장 연산자 - 3.산술연산자 (0) | 2017.06.26 |
[Java의 정석] 제 3장 연산자 - 1.연산자, 2.단항연산자 (0) | 2017.06.23 |
[Java의 정석] 제 2장 연산자 - 4.비교연산자, 5.그외의 연산자 (0) | 2017.06.22 |
댓글