전 글인 else, else if 부분에서 메뉴를 만들었는데 else if를 이용하는 건 좋은 방법이 아니다.(흐름이 메뉴를 만드는데 적절하지 않다)
else if의 문제점
메뉴가 늘어나면 늘어날 수록 흐름이 계속해서 길어지며 비교하는 내용도 계속 많아진다.
첫번째 선택된 메뉴는 빠르게 실행 될 수 있지만 메뉴가 많아졌을 때 마지막 메뉴는 실행이 느려진다.(앞에걸 다 거쳐서 지나가기 때문에)
분기문을 이용한 선택 흐름
제어를 만났을 때 1이면 1로 2면 2로 3이면 3으로 바로 번지해 실행될 수 있게 하는 것이 switch문이다.
하지만 case 1,2,3이 모두 있을 때 1을 선택하면 그 아래로 내리 실행되는데 이를 막기 위해 끊어줄 수 있는 제어문이 필요한데 이것이 break;(감싸고 있는 switch문을 통째로 벗어남)
여기서 보통 매 블럭마다 break;를 써주는 게 일반적인데 의도적으로 1번 선택후 2까지 자동 실행 되도록 break;를 쓰지 않을 수도 있다.
종료: //앞서 변수나 Scanner 임포트 부분은 선언되었다고 생각하자.
while (true) {
//----------------메인 메뉴 부분 -------------------------------
System.out.println("┌──────────────────────────────────────┐");
System.out.println("│ 메인메뉴 │");
System.out.println("└──────────────────────────────────────┘");
System.out.println("\t1. 성적 입력");
System.out.println("\t2. 성적 출력");
System.out.println("\t3. 종료");
System.out.print("\t선택 >");
menu = scan.nextInt();
switch (menu) {
case 1: //받은 menu값이 1일 경우
//-----------------성적 입력 부분------------------------
System.out.println("┌──────────────────────────────────────┐");
System.out.println("│ 성적입력 │");
System.out.println("└──────────────────────────────────────┘");
do {
System.out.print("국어 1: ");
kor1 = scan.nextInt();
if (kor1 < 0 || 100 < kor1)
System.out.println("성적범위(0~100)를 벗어났습니다.");
} while (kor1 < 0 || 100 < kor1);
do {
System.out.print("국어 2: ");
kor2 = scan.nextInt();
if (kor2 < 0 || 100 < kor2)
System.out.println("성적범위(0~100)를 벗어났습니다.");
} while (kor2 < 0 || 100 < kor2);
do {
System.out.print("국어 3: ");
kor3 = scan.nextInt();
if (kor3 < 0 || 100 < kor3)
System.out.println("성적범위(0~100)를 벗어났습니다.");
} while (kor3 < 0 || 100 < kor3);
break;
case 2://받은 menu값이 2일 경우
//-----------------성적 출력 부분------------------------
total = kor1 + kor2 + kor3;
avg = total / 3.0f;
System.out.println("┌──────────────────────────────────────┐");
System.out.println("│ 성적출력 │");
System.out.println("└──────────────────────────────────────┘");
System.out.printf("%1$d %1$d %1$d\n", 1);
//for(int n=1; n<=3; i++)
for (int i = 0; i < 3; i++)
System.out.printf("\t국어%d : %3d\n", i + 1, kor1);
System.out.printf("\t총점 : %3d\n", total);
System.out.printf("\t평균 : %6.2f\n", avg);
System.out.println("──────────────────────────────────────");
break;
case 3://받은 menu값이 3일 경우
break 종료;
default ://기본값(case로 정의한 1~3까지의 값이 아닌 값이 들어올 때)
System.out.println("입력오류 1~3까지만 입력할 수 있습니다.");
}
}
System.out.println("good bye!");
여기서 case:3에 쓰여진 break 종료;는 그냥 break;를 쓸 경우 switch문만을 벗어나고 while문은 그대로이기 때문에 무한 루프에 빠지게 된다.
C언어에선 go to 문이라고 제어문이 중첩 되었을 때 저 안쪽에서 한번에 벗어나기 위해 쓴다거나 코드의 다른 지점으로 점프하도록 하는 제어 흐름 명령문이다.
하지만 숙달되지 않은 개발자에 의해서 코드의 난해함이 생길 수 있는 문제가 있어 Java에선 go to문에서 중첩문만을 벗어날 수 있는 break라벨문을 만든다.
위 그림에서 break만 썼을 경우 switch문만 벗어나게 되는데 라벨을 지정한 뒤 break 라벨;을 작성할 경우 라벨을 만날 때가지 벗어나게 된다.
그래서 코드 중간 부분 종료 : 라는 라벨을 만든뒤 break 종료; 라는 break 라벨;을 적어 while문 밖으로 탈출하도록 만들었다.