4장 - 조건에 따라 흐름 바꾸기: 조건문
자바 프로그램을 작성하면 보통 명령을 순차적으로(코드를 위에서 아래로) 실행한다. 하지만 조건에 따라 명령을 수행하거나 수행하지 않아야 할 때가 있다. 이럴 때 우리는 조건문을 사용하며, 이 장에서는 조건문을 어떻게 사용하는지 그리고 조건문의 종류로는 무엇이 있는지 살펴볼 것이다.
4.1. 조건이 하나일 때: if-else
조건문은 조건에 따라 실행하는 명령이 달라진다. 기본 형식은 다음과 같다.
조건을 만족하면 if 블록의 실행문이 출력되고, 조건을 만족하지 않으면 else 블록의 실행문이 출력된다.
if ([조건]) {
[실행문]; //조건을 만족할 때 실행할 명령문
}
else{
[실행문]; //조건을 만족하지 않을 때 실행할 명령문
}
if-else 문에서 중괄호{}는 실행할 명령문의 범위를 명시하며, 실행할 명령문이 하나일 경우 중괄호를 생략해도 된다. 하지만 입문자는 형식을 익히는 것이 중요하므로 앞으로의 코드에서는 중괄호를 생략하지 않고 모두 표시할 것이다.
4.1.1. 조건을 만족할 때(if) / 조건을 만족하지 않을 때(else) ★
public class Main {
public static void main(String[] args) {
int score = 90;
if (score >= 90) {
System.out.println("A학점입니다.");
}
else{
System.out.println("A학점이 아닙니다.");
}
}
}
// A학점입니다.
// int score = 90;
score라는 정수형 변수를 선언하고, 점수를 넣어 변수를 초기화한다.
// if (score >= 90)
"score가 90 이상"을 조건으로 한다. >=는 이상을 나타내는 연산자이다. score의 현재 값은 90이고, if문의 조건에서 score의 값이 90 이상인지 확인한다. 여기서는 조건을 만족하므로 if문의 명령문을 실행한다.
//else
만약 score가 90이 아닌 80이라고 한다면, 이번에는 조건에 만족하지 않으므로 else문의 명령문이 실행될 것이다.
이처럼 조건문의 조건을 만족할 때, 판단 결과가 참일 때를 true라고 하고 만족하지 않을 때, 즉 거짓일 때를 false라고 한다. 순서도와 함께 이해해보자. 마름모는 판단을 의미하며, 조건에 따라 분기된다. 직사각형은 연산이나 처리 과정을 나타내고, 화살표는 프로그램의 흐름을 나타내는 선이다.
순서도를 작성하면 프로그램의 흐름을 한눈에 볼 수 있으므로, 프로그램을 작성하기 전에 그려보면 도움이 된다.
4.1.2. 비교 연산자
값을 비교하는 연산자를 비교 연산자라고 한다. 앞에서 봤던 >=도 비교 연산자이다. 자바에서 사용하는 비교 연산자는 다음과 같다.
연산자 | 설명 |
== | 왼쪽과 오른쪽이 같으면 참 |
!= | 왼쪽과 오른쪽이 같지 않으면 참 |
> | 왼쪽이 오른쪽보다 크면 참 |
< | 왼쪽이 오른쪽보다 작으면 참 |
>= | 왼쪽이 오른쪽보다 크거나 같으면 참 |
<= | 왼쪽이 오른쪽보다 작거나 같으면 참 |
4.1.3. QUIZ
문제 설명)
다음 코드는 입력받은 정수가 짝수면 '짝수'라고 출력하고, 홀수이면 '홀수'라고 출력한다. 빈칸에 알맞은 코드를 작성하시오.
내가 짠 코드) - 맞음. 정답 코드에는 num%2 == 1로 조건을 작성함
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
if (num%2 != 0){ //조건문이 빈칸
System.out.println("홀수");
}
else{
System.out.println("짝수");
}
}
}
/*7
홀수*/
4.2. 조건이 여러 개일 때: else if ★
- if-else문: 조건이 하나고, 이를 만족하는 경우와 아닌 경우로 나뉠때 사용(true or false)
- else if문: 조건이 여러개일 때 사용
else if 블록을 사용하는 조건문 형식은 다음과 같다. 각각의 조건문에 true일 때 진입하며, false일 경우 조건에 맞는 조건문이 있을 때까지 내려간다. 조건에 맞는 조건문이 없다면 else의 명령문이 출력된다. 가장 먼저 if문이 오며, else if 블록은 조건 개수에 따라 n번 사용할 수 있다. 단, if문 없이 단독으로 사용할 수는 없다.
if ([조건1]) {
[실행문1]; //조건1을 만족할 때 실행할 명령문
}
else if ([조건2]) {
[실행문2]; //조건2를 만족할 때 실행할 명령문
}
else if ([조건3]) {
[실행문3]; //조건3을 만족할 때 실행할 명령문
}
...
else {
[실행문n]; //모든 조건을 만족하지 않을 때 실행할 명령문
}
형식에 맞춰 학점 출력 코드를 작성해보자. 조건은 "90점 이상(A), 80점 이상(B), 70점 이상(C), 그 외(D)" 4가지이다. 구조가 복잡하니 알기 쉽게 먼저 순서도로 표현해 보겠다.
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("score을 입력하세요:");
int score = scan.nextInt();
if (score >= 90){
System.out.println("A학점입니다.");
}
else if (score<90 && score>=80){
System.out.println("B학점입니다.");
}
else if (score<80 && score>=70){
System.out.println("C학점입니다.");
}
else{
System.out.println("D학접입니다.");
}
}
}
/*
score을 입력하세요:88
B학점입니다.
*/
※수학에서는 '80점 이상 90점 미만'이라는 조건을 '80 <= score < 90'으로 한 번에 쓸 수 있지만 자바에서는 그렇지 않다.
자바에서는 조건을 나눠서 'score >= 80'과 'score < 90'으로 써야하며, 조건이 2개 이상일 경우에는 여러 조건을 동시에 판단하는 연산자를 사용한다. 여기에서는 && 논리 연산자가 사용되었다.
4.2.1. 논리 연산자
아래의 세 연산자를 합쳐 논리 연산자라고 한다.
연산자 | 설명 |
&& | 왼쪽과 오른쪽 모두 참이면 참(TT를 찾음) |
|| | 왼쪽과 오른쪽 중 하나라도 참이면 참(FF를 찾음) |
! | 조건을 만족하면 거짓, 조건을 만족하지 않으면 참 |
4.2.2. QUIZ
문제 설명)
학점을 출력하는 코드에서 else if 블록의 조건은 논리 연산자를 사용하지 않도록 바꿀 수 있다. if 문의 조건을 참고해 빈칸에 알맞은 내용을 작성하세요.
내가 짠 코드) - 정답
if문의 조건(90이상)을 충족하지 못해 else if로 내려온 거니(score < 90임을 의미), 굳이 90보다 작다는 조건을 추가로 적어서 논리 연산자를 사용 할 필요가 없다.
public class Main {
public static void main(String[] args){
int score = 80;
if (score >= 90){
System.out.println("A학점입니다.");
}
else if (score >= 80){ //(1)
System.out.println("B학점입니다.");
}
else if (score >= 70){ //(2)
System.out.println("C학점입니다.");
}
else{
System.out.println("D학점입니다.");
}
}
}
4.3. 조건문 안에 조건문이 있을 때: 중첩 조건문
4학년에게 점수가 90점 이상이면 장학금을 지급한다고 한다. 학년과 점수를 입력방아 장학금 지급 대상자인지 확인하는 코드를 작성해보자.
(1) 4학년인지 판별 -> true, false
(2) (1)의 결과가 true인 것 중, 점수가 90점 이상인지 아닌지 판별
public class Main {
public static void main(String[] args){
System.out.print("학년을 입력하세요:");
Scanner scanGrade = new Scanner(System.in); //scanGrade
int grade = scanGrade.nextInt();
if (grade == 4){
System.out.print("점수를 입력하세요:");
Scanner scanScore = new Scanner(System.in); //scanScore
int score = scanScore.nextInt();
if (score >= 90){
System.out.print("장학금 지급 대상입니다.");
}
else {
System.out.print("장학금 지급 대상이 아닙니다.");
}
}
else {
System.out.print("장학금 지급 학년이 아닙니다.");
}
}
}
조건의 범위를 잘 파악하면 중첩 조건문을 쉽게 작성할 수 있다. 그러나 중첩이 반복되면 코드가 복잡해지므로 3개 이상은 사용하지 않는것이 좋다.
4.3.1. QUIZ ★
조건)
숫자를 입력받아 양수인지 확인한다. 양수라면 홀수인지 짝수인지 확인한다. 확인 결과 홀수이면 '홀수'라고 출력하고, 짝수면 '짝수'라고 출력한다. 양수가 아니라면 양수를 입력하라고 출력한다.
코름 흐름도 작성) - 정ㄷ답
(1) 양수인지 판단 -> true, false
(2) (1)의 true에서 홀수인지 짝수인지 판단 -> true, false/ 홀수와 짝수는 2로 나눈 나머지가 1이나 0이냐의 차이
public class Main {
public static void main(String[] args){
System.out.print("양수를 입력하세요:");
Scanner scanNum = new Scanner(System.in);
int Num = scanNum.nextInt();
if (Num > 0){
if (Num % 2 == 1){
System.out.print("홀수입니다."); //나머지가 1이면 홀수
}
else{
System.out.print("짝수입니다."); //
}
}
else{
System.out.print("양수를 입력하세요.");
}
}
}
4.4. 조건과 일치하는 값 찾기: switch
4.4.1. switch문 ★
조건문에는 if-else 문 외에도 switch문이 존재한다. switch문도 if-else 문처럼 조건에 따라 실행할 명령이 달라진다. 기본 형식은 아래와 같다.
switch ([조건]) {
case ([값1]): //;가 아닌 :임
[실행문1];
break;
...
default: //생략 가능
[실행문];
break;
}
case 믈록의 수는 비교할 값의 개수에 따라 달라지며, 값은 조건과 같은 자료형이어야 한다. 또한 case 블록 끝에는 break 문이 들어가는데, break는 해당 case 블록이 조건을 만족할 떄 switch 문을 탈출하게 하는 역할을 한다.
switch문을 실행하면 '조건'과 'case 블록의 값'을 순서대로 비교한다. 그러다 값이 일치하는 case 블록을 만나면 해당 case 블록에 속한 명령문을 실행한다. 만약 값이 일치하는 case 블록이 없다면 default 블록으로 가서 명령문을 실행한다. default 블록은 생략 가능하다. default는 조건과 일치하는 case 블록이 없을 때 실행되므로 switch문 어디든 작성해도 되지만, 일반적으로 코드 흐름을 파악하기 쉽도록 코드의 마지막에 작성하는 편이다.
학점을 출력하는 예제와 함께 이해해보자.
public class Main {
public static void main(String[] args){
System.out.print("점수를 입력하세요:");
Scanner scanScore = new Scanner(System.in);
int score = scanScore.nextInt();
switch (score){
case(90):
System.out.print("A학점입니다.");
break;
case(80):
System.out.print("B학점입니다.");
break;
case(70):
System.out.print("C학점입니다.");
break;
default:
System.out.print("90, 80, 70 중 하나를 입력하세요.");
}
}
}
/*점수를 입력하세요:77
90, 80, 70 중 하나를 입력하세요.*/
// switch (score) {...}
조건이 score이다. 그리고 값에 각각 90, 80, 70이 적혀있다.
-> score이 90, 80, 70일 떄, 각각의 case 블록에 적혀있는 명령문이 출력되는 구조이다.
4.4.2. if문과 switch문 ★
switch문으로 코드를 작성하면, if문을 사용한 경우보다 조건이 명확하고 단순해진다.
- if문: 범위에 해당하는 값을 비교할 때 사용
- switch문: 정확하게 정해진 값을 비교할 때 사용
4.4.3. switch 문에서 주의할 점 - break 생략
각 case 블록 끝에 있는 break는 생략 가능하다. 단, 이 경우(break을 생략하면) 조건문을 탈출하지 않고 다음 case 블록으로 넘어간다. 즉, case 블록에 break를 넣지 않으면 switch 문을 종료하지 않고 다음 case블록도 계속 실행하므로 이 점을 주의해야한다.
public class Main {
public static void main(String[] args){
System.out.print("점수를 입력하세요:");
Scanner scanScore = new Scanner(System.in);
int score = scanScore.nextInt();
switch (score){
case(90):
System.out.print("A학점입니다.");
// break; 주석처리하면??
case(80):
System.out.print("B학점입니다.");
break;
case(70):
System.out.print("C학점입니다.");
break;
default:
System.out.print("90, 80, 70 중 하나를 입력하세요.");
}
}
}
/*점수를 입력하세요:90
A학점입니다.B학점입니다.*/
4.4.4. QUIZ
다음 코드의 실행 결과는?
public class Main {
public static void main(String[] args){
int input = 1;
switch(input){
case (1):
System.out.print("1");
case (2):
System.out.print("2");
case (3):
System.out.print("3");
}
}
}
답) 123
-> 각 case문에 break가 없기 때문에 해당 다음 case문으로 계속 넘어가기 때문이다.
4.5. 삼항 연산자
4.5.1. 삼항 연산자 ★
if문, switch문의 조건을 작성하다 보면 코드가 상당히 길어지는 경우가 있다. 이 때 삼항 연산자(conditional operator)을 사용하면 편하다. 삼항 연산자를 사용하면 조건을 한 줄로 작성할 수 있어, 조건문의 코드 줄 수를 줄일때 사용된다.
기본 형식은 다음과 같다.
([조건])? A:B
구분 | 의미 |
조건 | true 또는 false 값을 반환하는 조건이 들어간다 |
A | 조건의 결과가 true일 때 선택되는 것 |
B | 조건의 결과가 false일 때 선택되는 것 |
-> 조건의 결과는 true 또는 false이기 때문에, 2개 이상의 조건을 판별해야 하는 상황에서는 삼항 연산자 사용은 적합하지 않다.
예시와 함께 이해해보자.
public class Main {
public static void main(String[] args){
System.out.print("점수를 입력하세요:");
Scanner scanScore = new Scanner(System.in);
int score = scanScore.nextInt();
String grade = (score >= 90)?"A학점입니다":"B학점입니다";
System.out.println(grade);
System.out.println(grade + "-> 라고 하네요");
}
}
/*점수를 입력하세요:98
A학점입니다
A학점입니다-> 라고 하네요*/
// String grade = (score >= 90)?"A학점입니다":"B학점입니다";
사용자로부터 score을 입력 받고, 만약 score값이 90 이상이면 조건의 결과가 true일 때 출력되는 "A학점입니다"가 출력된다. 만약 score값이 90 이하이면 조건의 결과가 false일 떄 출력되는 "B학점입니다"가 출력된다.
※헷갈린점
: score >= 90을 case(90)으로 이해해서, 만약 98을 score에 입력하면 아무 명령어도 출력되지 않을 것이라고 생각했다.
-> score >= 90의 결과는 무조건 true 또는 false이다! 왜 헷갈렸는지는 잘 모르겠지만 앞으로 주의하자.
4.5.2. QUIZ
문제)
다음 코드는 입력받은 정수가 짝수면 '짝수'라고 출력하고 홀수면 '홀수'라고 출력한다. 삼항 연산자를 사용하여 코드를 만들어라
내가 짠 코드) - 정답
String string_num을 통해, 삼항연산 결과(true, fasle)를 string_Num이라는 String 자료형 변수에 저장한다. 이후 System.out.print(string_Num)을 통해 string_Num(홀수 또는 짝수)을 출력하도록 했다.
public class Main {
public static void main(String[] args){
System.out.print("정수를 입력하세요:");
Scanner scanNum = new Scanner(System.in);
int Num = scanNum.nextInt();
String string_Num = (Num % 2 == 1)?"홀수":"짝수";
System.out.print(string_Num);
}
}
/*정수를 입력하세요:216
짝수*/
마무리
1. if문
(1) 둘 이상의 조건을 판단하거나, 조건의 참과 거짓을 부정할 때는 다음과 같은 논리 연산자를 사용한다.
- && (논리 곱): 왼쪽과 오른쪽 모두 참이면 참
- || (논리 합): 왼쪽과 오른쪽 중 하나라도 참이면 참
- ! (논리 부정 연산자): 조건을 만족하면 거짓, 조건을 만족하지 않으면 참 -> reverse
2. 중첩 조건문
(1) 조건문 안에 조건문이 있을 때 이를 중첩 조건문이라고 한다
(2) 내부 조건문은 외부 조건문이 참(ture)일 때만 실행된다
3. switch문
(1) 정확히 정해진 값을 비교할 때 사용
(2) 값이 일치하는 case문을 만나면, 해당 case문의 실행문을 실행한 뒤 break문을 만나며 switch문을 탈출한다. 만약 조건과 일치하는 case 블록이 없다면 default 블록으로 이동해 default 블록의 실행문을 실행하고 switch문을 탈출한다
(3) case 블록 끝에 break가 온다. 이때 break는 생략 가능하지만.... 생략할 일이 있을까 싶다
4. 삼항 연산자
(1) 삼항 연산자를 사용하면 if-else 문의 조건 부분을 한 줄로 작성할 수 있다. 즉, 조건문의 코드 줄 수를 줄이는 역할을 한다.
(2) (조건)?"A":"B"의 형식이며, String grade = (score >= 90) ? "A학점입니다" : "B학점입니다";를 예제로 들 수 있다.
마무리 Test
조건)
1. 알파벳 소문자를 입력받아 대문자로 변환해 출력하는 프로그램을 switch문으로 작성해라
2. a, b, c 외 다른 문자를 입력받으면 일치하는 알파벡시 없다고 출력하고 switch문을 종료한다. 그 밖의 예외 사항은 고려하지 않는다
내가 짠 코드) - 갓벽함
public class Main {
public static void main(String[] args){
System.out.print("알파벳을 입력하세요(a,b,c중 하나):");
Scanner scan = new Scanner(System.in);
String str = scan.nextLine();
switch(str){
case("a"):
System.out.print("A");
break;
case("b"):
System.out.print("B");
break;
case("c"):
System.out.print("C");
break;
default:
System.out.print("일치하는 알파벳이 없습니다.");
}
scan.close(); //작성하면 컴퓨터 환경에 좋음
}
}
/*알파벳을 입력하세요(a,b,c중 하나):f
일치하는 알파벳이 없습니다.*/