개발 지식/Java

[Java] break / continue

devGSP 2022. 7. 20. 08:00
반응형
이 게시물은 아래 버전을 기준으로 작성되었습니다.

Java : 11.0.15.1
OS : Windows 10 Pro
IDE : Eclipse IDE for Enterprise Java and Web Developers - 2022-06

 

break / continue

 

반복문을 중간에 중단시킬 순 없을까?

 

이전 포스트(링크)에서 자습 예제로 이러한 문제를 냈다. 

 

반복문 내 선언한 int형 변수를 1부터 100까지 1씩 증감시키는 for 반복문을 작성하고, 변수가 25에 도달했을 때 "25번 자료를 검사합니다." 메시지를 출력하는 코드를 작성해 보자. 단, 해당 반복문을 3회 반복시키고, 메시지가 출력될 때마다 몇 번째 시도인지 알 수 있게 아래와 같이 출력되도록 코드를 작성해 보자.

 

그리고 필자가 여기에 대한 예시 답안으로 작성한 코드는 아래와 같다.

 

 

package com.devgsp.study.basic;

public class MyDupLoop {
	public static void main(String[] args) {
		for (int i = 1; i <= 3; i++) {
			for (int j = 1; j <= 100; j++) {
				if (j == 25) {
					System.out.println("[" + i + "phase]");
					System.out.println(j + "번 자료를 검사합니다.");
				}
			}
		}
	}
}

 

만약 눈치가 빠른 사람이라면 이 코드에 어떠한 의문을 품었을 수도 있다. 별로 의문이 들지 않았다면 그것은 아마도 출력된 결과가 원하는 방향으로 나왔기 때문일지도 모른다.

그렇다면 아래 대화 형식의 글을 읽어 보고 다시 한번 생각해 보자.

 

상사 : GSP 씨, 저기 자료 100개가 있는데 저기서 25번 자료 좀 찾아서 가져와요.
GSP : ㅇㅋㄷㅋ염

(뒤적뒤적)

GSP : 25번 자료 찾았당 ㅎㅎ
상사 : 수고했어요. 어서 가져오세요.

(뒤적뒤적)

상사 : 안 가져오고 뭐 하세요?
GSP : 아직 나머지 75개 자료를 안 봤음요 ㅎㅎ

 

즉, 현재 작성된 코드는 단순히 int형 변수 j가 25일 때 메시지를 출력해 주고, 다른 조건일 때 메시지를 출력하지 않았을 뿐이지, j가 100이 될 때까지 증감식은 계속해서 실행되고 있는 것이다.

 

그럼 코드를 조금 변경해서 실행해 보자.

 

 

package com.devgsp.study.basic;

public class Break1 {
	public static void main(String[] args) {
		for (int i = 1; i <= 100; i++) {
			System.out.println("현재 i : " + i);
			if (i == 25) {
				System.out.println(i + "번 자료를 찾았습니다.");
			}
		}
	}
}

 

break1
Break1.java 실행 결과

 

즉, 위의 GSP와 상사의 대화대로라면 위의 실행 결과에서 빨간색으로 표시한 부분이 출력되는 차례에 반복문을 중단시켜야 되는 것이다.

 

 

break

 

이럴 때 사용하는 것이 break 명령어이다. break 명령어는 루프문에서 사용할 경우 해당 루프문을 강제로 종료시키고 빠져나가는 기능을 한다. break 명령어를 추가해 코드를 수정한 뒤 재실행시켜 보자.

 

 

package com.devgsp.study.basic;

public class Break1 {
	public static void main(String[] args) {
		for (int i = 1; i <= 100; i++) {
			System.out.println("현재 i : " + i);
			if (i == 25) {
				System.out.println(i + "번 자료를 찾았습니다.");
				break;	// break 명령어로 강제로 반복문을 중단시킬 수 있다!
			}
		}
	}
}

 

break2
Break1.java 실행 결과2

 

 

break label

 

반복문을 중첩으로 작성한 경우에도 break를 사용할 수 있다. 그러나 중첩하여 작성한 경우 반복문 안에 작성한 반복문만을 빠져나갈 것인지, 중첩 반복문 전부를 빠져나갈 것인지에 따라 작성 방법에 차이를 두어야 한다.

만약 당신이 i == 1, j = 2일 때 이중으로 작성된 중첩 반복문 전부를 빠져나가는 프로그램을 작성하려는 의도였으며, 아래와 같이 코드를 작성했다고 가정하자.

 

 

package com.devgsp.study.basic;

public class Break2 {
	public static void main(String[] args) {
		// i == 1, j = 2일 때 중첩문을 빠져나가고 싶다고 가정!
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				System.out.println("현재 i : " + i + " / j : " + j);
				if (i == 1 && j == 2) {
					System.out.println("이제 나가요!");
					break;
				}
			}
		}
		System.out.println("나왔어요!");
	}
}

 

 

그러나 위 코드를 실행하면 아래와 같은 결과가 나온다.

 

 

break3
Break2.java 실행 결과

 

 

작성한 의도대로라면 "이제 나가요!"가 출력된 후 "나왔어요!" 가 출력되어야 하지만, break는 안에 있는 반복문만을 탈출하여 바깥에 작성된 증감식으로 돌아가 버린 것이다.

이럴 경우 브레이크 레이블(break label)이라는 것을 이용하면 된다. 이름에서 추측해 볼 수 있듯, break가 되는 지점을 표시해 주는 것이다.

 

위 코드를 아래와 같이 수정해 보자.

 

 

package com.devgsp.study.basic;

public class Break2 {
	public static void main(String[] args) {
		// i == 1, j = 2일 때 중첩문을 빠져나가고 싶다고 가정!
		
		// outerForLoop라는 명령어가 존재하는 것이 아님
		// 특정한 반복문에 레이블을 작성해 주는 것이다.
		outerForLoop:
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				System.out.println("현재 i : " + i + " / j : " + j);
				if (i == 1 && j == 2) {
					System.out.println("이제 나가요!");
					break outerForLoop;
					// outerForLoop라는 반복문을 빠져나간다는 의미
				}
			}
		}
		System.out.println("나왔어요!");
	}
}

 

break4
Break2.java 실행 결과2

 

 

의도한 부분에서 중첩문을 빠져나가는 것을 확인할 수 있다.

 

 

반복문에서 조건 불일치 시 불필요한 작업을 사전에 차단할 순 없을까?

 

이번엔 비슷하지만 조금 다른 경우를 생각해 보자. break는 특정 조건을 만족했을 경우 반복문을 중단시키고 빠져나가는 명령어였다. 그렇다면 특정 조건을 만족하지 않을 경우 사전에 차단하여 불필요한 메모리 낭비를 줄일 방법은 없을까?

 

아래는 1부터 100까지의 정수 사이에 있는 3과 5의 공배수의 개수를 구하는 예시 코드다. 이번에는 for 반복문이 아닌 while 반복문으로 작성해 보았다.

 

package com.devgsp.study.basic;

public class Continue1 {
	public static void main(String[] args) {
		int idx = 1;	// 100까지 루프를 돌리고, 최소공배수를 저장할 변수
		int cnt = 0;	// 3과 5의 공배수의 개수를 저장할 변수
		
		while (idx <= 100) {
			if (idx % 3 == 0 && idx % 5 == 0) {
				System.out.println(idx + " : 3와 5의 공배수 O");
				cnt++;
			} else {
				System.out.println(idx + " : 3와 5의 공배수 X");
			}
			System.out.println(idx + " 검사 완료");
			idx++;
		}
		System.out.println("1과 100 사이에 있는 3과 5의 공배수의 수 : " + cnt);
	}
}

 

Continue1
Continue1.java 실행 결과

 

 

위 코드의 과정과 결과에 오류는 없다. 다만, 결과를 도출하는 데 불필요한 작업이 많이 실행되고 있다.

 

 

continue

 

이런 상황에서는 continue 명령어를 사용할 수 있다. continue 명령어는 명령어보다 아래에 있는 코드들을 실행하지 않고 바로 반복문의 조건 검사식으로 돌아가는 기능을 한다. 즉, 조건 변화식이 continue 명령어 실행보다 뒤에 실행되는 설계라면 무한루프에 빠질 수도 있으니 사용에 주의가 필요하다. (특히 while 반복문 작성 시 주의!)

 

아래에 Continue1.java 코드를 살짝 변경하여 Continue2.java를 작성하였다.

 

 

package com.devgsp.study.basic;

public class Continue2 {
	public static void main(String[] args) {
		// Continue while 예제
		int idx = 1;	// 100까지 루프를 돌리고, 최소공배수를 저장할 변수
		int cnt = 0;	// 3과 5의 공배수의 개수를 저장할 변수
		
		while (idx <= 100) {
			if (idx % 3 != 0 || idx % 5 != 0) {	// 3과 5의 공배수가 아니면
				idx++;	// 이게 없으면 큰일이 난다 ㅋㅋ..
				continue;
			} 
			System.out.println(idx + " 검사 완료");
			cnt++;
			idx++;
		}
		System.out.println("1과 100 사이에 있는 3과 5의 공배수의 수 : " + cnt);
		System.out.println("===========================");
		// Continue for 예제
		int cnt2 = 0;
		for (int i = 1; i <= 100; i++) {
			if (i % 3 != 0 || i % 5 != 0) {	// 3과 5의 공배수가 아니면
				continue;
			} 
			System.out.println(i + " 검사 완료");
			cnt2++;
			i++;
		}
		System.out.println("1과 100 사이에 있는 3과 5의 공배수의 수 : " + cnt2);
	}
}

 

Continue2
Continue2.java 실행 결과

 

 

 

[예제]

1. com.devgsp.study.basic
패키지에 MyBreakContinue 클래스를 생성하자.
2. 아래 내용의 코드를 반복문을 활용해 작성하자(단, 반복문은 for, while 아무거나 사용하여도 무방하다).

a
. 1로 초기화한 int형 변수를 100까지 1씩 증가되도록 한다.
b. 설정한 int형 변수의 조건과 관련하여 아래 내용의 분기문들을 작성한다.

b-1. int형 변수가 6과 14의 최소공배수일 때 해당 변수를 출력하고 반복문의 실행을 중단시킨다.
b-2. int형 변수가 6 혹은 14의 배수가 아니면 조건 검사식으로 돌아가게 한다.
b-3. int형 변수가 그 외의 조건이면 "이 메시지는 출력되면 안 됩니다."를 출력하도록 설정한다. 메시지대로 실제로 출력되어선 안 된다.

 

더보기
package com.devgsp.study.basic;

public class MyBreakContinue {
	public static void main(String[] args) {
		// for 예시 답안
		for (int i = 1; i <= 100; i++) {
			if (i % 6 == 0 && i % 14 == 0) { // 6와 14의 공배수면
				System.out.println("6와 14의 최소공배수 : " + i);
				break;
			} else if (i % 6 != 0 || i % 14 != 0) {
				continue;
			} else {
				System.out.println("이 메시지는 출력되면 안 됩니다.");
			}
		}
		System.out.println("=============================");
		
		// while 예시 답안
		int index = 1;
		while (index <= 100) {
			if (index % 6 == 0 && index % 14 == 0) { // 6와 14의 공배수면
				System.out.println("6와 14의 최소공배수 : " + index);
				break;
			} else if (index % 6 != 0 || index % 14 != 0) {
				index++;
				continue;
			} else {
				System.out.println("이 메시지는 출력되면 안 됩니다.");
			}
		}
	}
}

 

Continue3
MyBreakContinue.java 실행 결과

 

반응형

'개발 지식 > Java' 카테고리의 다른 글

[Java] 메서드(1) - 메서드의 정의  (0) 2022.08.01
[Java] 중첩 반복문  (0) 2022.07.19
[Java] For 반복문  (0) 2022.07.18
[Java] While / Do-While 반복문  (0) 2022.07.17
[Java] Switch 분기문  (0) 2022.07.16