반복문의 흐름 제어
break
현재 실행 중인 반복문을 즉시 종료시키는 기능을 가지고 있습니다. 주로 특정 조건이 만족되었을 때 더 이상 반복을 계속할 필요가 없을 경우 사용됩니다. break는 for, while, do-while 반복문과 switch 문 내에서 사용할 수 있으며, 가장 가까이 있는 반복문 하나만을 종료시킵니다.
break문은 특정 조건을 만족하게되면 반복문을 종료시키기위해 주로 if문과 함께 사용됩니다. 다음 예제 코드를 확인해볼까요?
public class Repeat05 {
public static void main(String[] args) {
for(int i = 0; i <= 10; i++) {
if(i == 5) {
break;
}
System.out.print(i + " ");
}
}
}
- 출력 결과 -
0 1 2 3 4
해당 예제 코드 for문의 조건식을 살펴보면 i가 0 부터 10이 될때까지 반복하게 되어있습니다. 하지만 for문의 코드 블록을 살펴보면 if문에 i가 5일때 반복문을 즉시 종료하게 되어있습니다. i가 5일 경우 반복문이 즉시 종료하게 되니, 5를 출력하지 않은 0부터 4까지만 출력하게 됩니다.
실습 예제
다음은 break문을 사용하여 숫자 맞추는 up & down 게임을 만든 예제입니다. random() 함수를 이용하여 임의의 수(1~100)를 만들고, 해당 수를 맞추는 게임입니다! 맞출 경우 게임이 종료되고, 틀릴 경우 계속 진행됩니다.
- 실습 예제 -
import java.util.Scanner;
public class Repeat06 {
public static void main(String[] args) {
// Scanner 클래스를 이용하여 콘솔로부터 사용자 입력을 받을 수 있는 scanner 객체를 생성합니다.
Scanner scanner = new Scanner(System.in);
// Math 클래스의 random메서드를 통해 1 ~ 100의 수를 임의로 생성합니다.
int number = (int) (Math.random() * 100) + 1;
// 사용자로부터 입력받을 수를 저장할 input 변수를 선언합니다.
int input;
System.out.println("up & down 게임을 시작합니다! 생성된 숫자를 맞춰주세요.");
while(true) {
// 사용자로부터 수를 입력받습니다.
input = scanner.nextInt();
if(number == input) {
System.out.println("정답입니다~ 생성된 숫자는 " + number + "입니다!");
break;
}
if(number > input){
System.out.println("up!");
} else {
System.out.println("down!");
}
}
}
}
- 출력 결과 -
up & down 게임을 시작합니다! 생성된 숫자를 맞춰주세요.
50
down!
25
down!
13
up!
19
up!
22
down!
21
down!
20
정답입니다~ 생성된 숫자는 20입니다!
* 해당 up & down게임은 실행할 때 마다 결과가 다르게 나옵니다.
💡 Java의 Math 클래스에 있는 random() 메서드는 0.0 이상 1.0 미만의 범위에서 double 타입의 난수(랜덤 값)를 생성하여 반환합니다. 위 예제는 1~100의 수를 얻기 위해 (0.0~0.9의 수 * 100) + 1 의 수식을 사용했습니다. 그리고 해당 수식의 결과는 double타입이므로 명시적 형변환을 통해 int 타입으로 변환하였습니다.
continue
반복문의 현재 사이클에서 남은 코드의 실행을 건너뛰고, 반복문의 다음 사이클로 즉시 이동합니다. 특정 조건을 만족하는 경우에만 일부 로직을 건너뛰고 반복문을 계속 진행하고 싶을 때 유용하게 사용됩니다.
continue문은 특정 조건을 만족하게되면 반복문을 건너뛰기위해 주로 if문과 함께 사용됩니다. 다음 예제 코드를 확인해볼까요?
public class Repeat07 {
public static void main(String[] args) {
for(int i = 0; i <= 10; i++) {
if(i % 2 == 0) {
continue;
}
System.out.print(i + " ");
}
}
}
- 출력 결과 -
1 3 5 7 9
해당 예제 코드 for문의 조건식을 살펴보면 i가 0 부터 10이 될때까지 반복하게 되어있습니다. 하지만 for문의 코드 블록을 살펴보면 if문에 i가 2로 나누었을때 나머지 값이 0일때는 반복문을 건너뛰게 되어있습니다. i % 2가 0일 경우 반복문을 건너뛰게 되니, i의 출력을 건너뛰게 됩니다. 따라서 홀수 값만 출력됩니다.
실습 예제
다음은 continue문을 사용하여 369 게임을 만든 예제입니다. 사용자가 입력한 수(10~100)까지 369 게임을 실행합니다. 3, 6, 9가 들어가는 숫자는 "짝!"을 출력합니다. 해당 숫자가 n번 들어갔다면, "짝!"도 n번 출력합니다.
- 실습 예제 -
import java.util.Scanner;
public class Repeat08 {
public static void main(String[] args) {
// Scanner 클래스를 이용하여 콘솔로부터 사용자 입력을 받을 수 있는 scanner 객체를 생성합니다.
Scanner scanner = new Scanner(System.in);
// 사용자로부터 입력받을 수를 저장할 input 변수를 선언합니다.
int input;
while(true) {
System.out.println("10 ~ 100까지의 숫자를 입력해주세요.");
// 사용자로부터 수를 입력받습니다.
input = scanner.nextInt();
// 10 ~ 100의 값을 입력할때까지 반복합니다.
if(input >= 10 && input <= 100) {
break;
}
}
System.out.println("369 게임을 시작합니다!" + input + " 까지 진행합니다!");
for(int i = 1; i <= input; i++) {
// 줄바꿈을 합니다.
System.out.println();
// 현재 수를 문자열로 변환합니다.
String numberStr = i + "";
// 박수를 쳤는지 안쳤는지 확인하는 변수입니다.
boolean isClap = false;
// 문자열을 char형 배열로 변환하고 3, 6, 9에 해당하는지 확인합니다.
for(char ch : numberStr.toCharArray()){
if(ch == '3' || ch == '6' || ch == '9'){
isClap = true;
System.out.print("짝! ");
}
}
// 박수 친 경우 숫자를 말하지 않습니다.
if(isClap) {
continue;
}
System.out.print(i);
}
}
}
- 출력 결과 -
10 ~ 100까지의 숫자를 입력해주세요.
10
369 게임을 시작합니다!10 까지 진행합니다!
1
2
짝!
4
5
짝!
7
8
짝!
10
💡 Java의 Math 클래스에 있는 toCharArray() 메서드는 문자열(String)을 문자 배열로 변환하여 반환합니다. 문자열을 구성하는 각 문자에 개별적으로 접근해야 할 때 매우 유용합니다. 예를 들어 "23" 은 toCharArray() 메서드를 사용하게 되면 ['2', '3'] 의 문자 배열로 변환됩니다. 위 예제는 각 문자가 3, 6, 9와 동일한지 확인하기 위해 해당 메서드를 사용했습니다.
중첩 반복문
중첩 반복문이란 반복문 내부에 다른 반복문이 포함되어 있는 구조를 말합니다. for, while, do-while 반복문의 어떤 조합으로도 구성될 수 있습니다. 이러한 구조는 다차원 배열의 데이터를 처리하거나, 복잡한 데이터 구조를 순회할 때, 그리고 알고리즘에서 여러 데이터를 처리할 필요가 있을 때 유용하게 사용됩니다.
중첩 반복문의 구조는 아래와 같은 형식의 구조를 갖습니다.
이 예제에서 바깥쪽 반복문은 3번 반복되고, 안쪽 반복문은 바깥쪽 반복문의 각 반복마다 3번씩 반복됩니다. 따라서 안쪽반복문에서 총 9번의 출력이 발생합니다.
아래의 표는 위 그림의 코드가 실행 시 바깥쪽 for문의 변수 i 와 안쪽 for문의 변수 j 의 변화를 나타낸 표입니다.
실습 예제
다음은 중첩 반복문을 이용하여 체스판을 출력하는 예제 입니다. 사용자에게 임의의 수(1~9)를 입력받아서, n*n 크기의 체스보드를 출력 합니다.
- 실습 코드 -
import java.util.Scanner;
public class Repeat09 {
public static void main(String[] args) {
// Scanner 클래스를 이용하여 콘솔로부터 사용자 입력을 받을 수 있는 scanner 객체를 생성합니다.
Scanner scanner = new Scanner(System.in);
// 체스판의 크기를 저장할 상수 BOARD 변수를 선언합니다.
final int BOARD;
while(true) {
System.out.println("1 ~ 9까지의 숫자를 입력해주세요.");
// 사용자로부터 수를 입력받습니다.
int temp = scanner.nextInt();
// 1 ~ 9의 값을 입력할때까지 반복합니다.
if(temp >= 1 && temp <= 9) {
BOARD = temp;
break;
}
}
System.out.println(BOARD + " * " + BOARD + "크기의 체스보드판을 생성합니다.");
for(int i = 1; i <= BOARD; i++) { // 행을 순회하는 외부 반복문
for(int j = 1; j <= BOARD; j++) { // 열을 순회하는 내부 반복문
// 행과 열의 합이 짝수인 경우 흰색('□'), 홀수인 경우 검은색('■')으로 판단합니다.
if ((i + j) % 2 == 0) {
System.out.print("□ "); // 흰색 칸 출력
} else {
System.out.print("■ "); // 검은색 칸 출력
}
}
System.out.println(); // 한 행의 출력이 끝나면 개행하여 다음 행을 준비합니다.
}
}
}
- 출력 결과 -
1 ~ 9까지의 숫자를 입력해주세요.
5
5 * 5크기의 체스보드판을 생성합니다.
□ ■ □ ■ □
■ □ ■ □ ■
□ ■ □ ■ □
■ □ ■ □ ■
□ ■ □ ■ □
반복문의 라벨(label)
반복문의 라벨이란 말그대로 반복문(for, while, do-while)에 이름을 붙여주는 것 입니다. 라벨은 반복문의 앞에 위치하여 해당 반복문을 식별할 수 있는 이름을 제공합니다.
반복문에 라벨을 적용하는 방법은 아래와 같이 콜론( : )을 이용하여 적용합니다.
반복문에 이름을 붙여주는 이유는 뭘까요?
예를 들어 중첩 반복문을 통해서 구구단을 만들고, 3*5가 될 경우 반복문을 종료하는 코드를 작성하고 싶어서 아래와 같은 코드를 작성했습니다.
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <= 9; j++) {
if(i == 1 && j == 1){
// 4자리의 공간을 확보하고, 나머지 공간은 공백으로 채워집니다. -는 좌측 정렬을 의미합니다.
System.out.printf("%-4s", " ");
} else {
// 4자리의 공간을 확보하고, 나머지 공간은 공백으로 채워집니다. -는 좌측 정렬을 의미합니다.
System.out.printf("%-4d", j * i);
}
if(i == 3 && j == 5){
break;
}
}
System.out.println();
}
해당 코드의 결과는 어떻게 나올까요? 3*5가 되면 중첩 반복문이 종료 될까요? 한번 결과를 확인해보겠습니다.
- 출력 결과 -
2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81
break가 중첩 반복문을 종료하는게 아닌 가장 가까운 안쪽 반복문만 종료한 뒤 다음 바깥쪽 반복문이 실행되었습니다. break처럼 continue 또한 가장 가까운 반복문만 건너뛰게 됩니다. 우리가 안쪽 반복문에서 바깥쪽 반목문을 제어하려면 어떻게 해야할까요? 바로 라벨(Label)을 이용하는 것입니다!
다음은 라벨을 이용하여 위의 예제인 구구단을 3*5에서 올바르게 종료되게 수정한 코드입니다.
- 수정된 코드 -
public class Repeat10 {
public static void main(String[] args) {
outerFor :
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <= 9; j++) {
if(i == 1 && j == 1){
// 4자리의 공간을 확보하고, 나머지 공간은 공백으로 채워집니다. -는 좌측 정렬을 의미합니다.
System.out.printf("%-4s", " ");
} else {
// 4자리의 공간을 확보하고, 나머지 공간은 공백으로 채워집니다. -는 좌측 정렬을 의미합니다.
System.out.printf("%-4d", j * i);
}
if(i == 3 && j == 5){
break outerFor;
}
}
System.out.println();
}
}
}
- 출력 결과 -
2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15
이처럼 라벨을 사용하여 특정 반복문에 이름을 부여하고, 이 이름을 활용하여 내부 반복문에서 바깥쪽 반복문을 명시적으로 제어할 수 있습니다. for, while, do-while 반복문에 라벨을 사용할 수 있으며, 해당 라벨은 continue, break 키워드와 함께 사용할 수 있습니다. 각 키워드를 라벨과 사용하면 아래와 같이 정리 할 수 있습니다.
- continue : 지정된 라벨이 붙은 반복문의 다음 반복으로 직접 점프할 수 있습니다.
- break : 지정된 라벨이 붙은 반복문을 완전히 탈출할 수 있습니다.
읽어주셔서 감사합니다 😊
'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] 08. 객체 지향과 절차 지향의 차이 (0) | 2024.05.07 |
---|---|
[Java] 07. 배열과 다차원 배열 (0) | 2024.03.27 |
[Java] 05. 반복문 배우기 (for, while, do-while, 향상된 for문) (0) | 2024.03.27 |
[Java] 04. 조건문 배우기 (if, if-else, else if, switch) (0) | 2024.03.27 |
[Java] 03. 연산자란? (우선순위, 결합규칙) (1) | 2024.03.26 |