break와 continue
break로 반복 전체를 종료하고 continue로 현재 반복만 건너뛰는 실행 흐름과 올바른 사용 시점을 구분합니다.
반복문들은 강력하지만, 때로는 반복 중간에 특수한 상황이 발생하여 루프의 정상적인 흐름을 벗어나야 할 필요가 생깁니다.
이러한 상황에서 프로그램의 흐름을 유연하게 제어하기 위해 사용되는 두 가지 중요한 문이 바로 break와 continue입니다.
이 두 문은 반복문(그리고 switch 문) 내에서만 사용될 수 있으며, 루프의 동작 방식을 미세하게 조정하는 데 결정적인 역할을 합니다.
둘 다 반복문 안에서 흐름을 바꾸지만, 도착 지점이 완전히 다릅니다.
- break루프를 즉시 종료
break 목표를 찾았거나 더 반복할 이유가 없을 때 사용합니다. 실행 흐름은 반복문 바로 다음 코드로 이동합니다. 대표 상황 탐색 성공, 오류 발견, 무한 루프 탈출
- continue현재 반복만 건너뜀
continue 지금 항목만 처리하지 않고 다음 반복으로 넘어갑니다. 루프 자체는 계속 실행됩니다. 대표 상황 잘못된 입력 제외, 0 나누기 회피, 이미 처리한 항목 건너뛰기
break 문: 루프 즉시 종료
break와 continue는 반복문 안에서 실행 위치가 갈라집니다.
먼저 루프를 완전히 끝낼지, 현재 반복만 건너뛸지 구분합니다.
조건을 만나는 순간 break 는 루프 밖으로, continue 는 다음 반복 준비 단계로 이동합니다.
- 1. 조건 검사
조건 검사 i <= 10 같은 반복 조건을 확인
- 2. 본문 진입
본문 진입 이번 반복에서 처리할 값을 읽음
- break
루프를 끝내고 다음 문장으로 이동
- continue
본문 아래쪽을 건너뛰고 증감/검사로 이동
- 5. 다음 반복
다음 반복 증감식 또는 조건 검사 후 다시 판단
- break 경로
조건 충족 “더 볼 필요 없음”이 확정되면 남은 반복도 실행하지 않습니다. 도착 지점 반복문을 닫는 중괄호 다음 코드로 바로 나갑니다.
- continue 경로
조건 충족 “이번 값만 제외”가 목적이면 아래 처리 코드를 실행하지 않습니다. 도착 지점 for 는 증감식으로, while 은 조건 검사로 이동합니다.
break 문은 현재 실행 중인 반복문 또는 switch 문을 즉시 종료하고, 해당 문 바로 다음의 코드로 실행 흐름을 옮깁니다.
break 문이 실행되는 순간, 루프의 나머지 부분은 건너뛰어지고 루프 자체가 끝납니다.
- 특정 조건이 충족되었을 때 더 이상 반복할 필요가 없을 경우.
- 무한 루프 내에서 특정 조건에 따라 루프를 안전하게 탈출할 경우.
switch문에서 한case블록의 실행을 마친 후 다른case로 넘어가는fall-through를 방지할 경우 (지난 장에서 학습).
#include <iostream>
int main() {
std::cout << "1부터 10까지 출력 (5에서 break):" << std::endl;
for (int i = 1; i <= 10; ++i) {
if (i == 5) {
std::cout << "5가 되어 루프 종료!" << std::endl;
break; // i가 5가 되면 for 루프를 즉시 종료
}
std::cout << i << " ";
}
std::cout << "\n루프 밖으로 나왔습니다." << std::endl;
/* 출력:
1 2 3 4 5가 되어 루프 종료!
루프 밖으로 나왔습니다.
*/
return 0;
}#include <iostream>
int main() {
int num;
while (true) { // 무한 루프
std::cout << "양수를 입력하세요 (음수를 입력하면 종료): ";
std::cin >> num;
if (num < 0) {
std::cout << "음수가 입력되어 프로그램을 종료합니다." << std::endl;
break; // 음수가 입력되면 while 루프를 즉시 종료
}
std::cout << "입력하신 양수: " << num << std::endl;
}
std::cout << "프로그램이 완전히 종료되었습니다." << std::endl;
return 0;
}중첩 루프에서의 break:
break 문은 가장 가까운(자신을 둘러싸는) 하나의 루프 또는 switch 문만 종료시킵니다.
중첩된 루프에서 바깥쪽 루프까지 한 번에 종료시키려면 다른 논리(예: 플래그 변수)나 goto 문(권장되지 않음)을 사용해야 합니다.
#include <iostream>
int main() {
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (i == 1 && j == 1) {
std::cout << "내부 루프 break!" << std::endl;
break; // 이 break는 안쪽 for (j 루프)만 종료시킴
}
std::cout << "i: " << i << ", j: " << j << std::endl;
}
std::cout << "외부 루프 (i: " << i << ") 계속 진행 중" << std::endl;
}
/* 출력:
i: 0, j: 0
i: 0, j: 1
i: 0, j: 2
외부 루프 (i: 0) 계속 진행 중
i: 1, j: 0
내부 루프 break!
외부 루프 (i: 1) 계속 진행 중 // 외부 루프는 계속 실행됨
i: 2, j: 0
i: 2, j: 1
i: 2, j: 2
외부 루프 (i: 2) 계속 진행 중
*/
return 0;
}continue 문: 현재 반복 건너뛰기
continue 문은 현재 실행 중인 반복의 나머지 부분을 건너뛰고, 즉시 다음 반복(iteration)으로 넘어갑니다.
즉, 현재 반복 몸체 내의 continue 아래에 있는 코드들은 실행되지 않고, 루프의 조건 검사 단계로 돌아갑니다.
- 특정 조건이 충족되었을 때 현재 반복을 중단하고 다음 반복으로 넘어가야 할 경우.
- 특정 데이터를 처리할 수 없거나, 유효하지 않아 건너뛰고 다음 데이터로 넘어갈 경우.
#include <iostream>
int main() {
std::cout << "1부터 10까지의 짝수만 출력:" << std::endl;
for (int i = 1; i <= 10; ++i) {
if (i % 2 != 0) { // i가 홀수이면
continue; // 현재 반복 건너뛰고 다음 i 값으로 넘어감
}
std::cout << i << " "; // 홀수일 때는 이 코드가 실행되지 않음
}
std::cout << "\n루프가 완료되었습니다." << std::endl;
/* 출력:
2 4 6 8 10
루프가 완료되었습니다.
*/
return 0;
}#include <iostream>
int main() {
int numbers[] = {10, 5, 0, 8, 2}; // 배열 요소
for (int num : numbers) { // 범위 기반 for 문
if (num == 0) {
std::cout << "0이 발견되어 나눗셈을 건너뜁니다." << std::endl;
continue; // 현재 num이 0이므로 이 반복을 건너뛰고 다음 요소로
}
std::cout << "100 / " << num << " = " << (100 / num) << std::endl;
}
/* 출력:
100 / 10 = 10
100 / 5 = 20
0이 발견되어 나눗셈을 건너뜁니다.
100 / 8 = 12
100 / 2 = 50
*/
return 0;
}while/do-while 문에서의 continue 주의사항:
while 또는 do-while 문에서 continue가 사용될 때, 루프를 종료시키는 조건 변수의 증감(또는 변경)이 continue 이후에 있다면 문제가 발생할 수 있습니다.
continue가 실행되면 조건 변수 변경 코드가 건너뛰어지기 때문에 무한 루프에 빠질 위험이 있습니다.
#include <iostream>
int main() {
int count = 0;
while (count < 5) {
if (count == 2) {
std::cout << "Count 2를 건너뜁니다." << std::endl;
continue; // !주의! count++가 실행되지 않아 무한 루프!
}
std::cout << "Current count: " << count << std::endl;
count++; // 이 부분이 continue 때문에 건너뛰어질 수 있음
}
/* 출력:
Current count: 0
Current count: 1
Count 2를 건너뜁니다.
Count 2를 건너뜁니다.
Count 2를 건너뜁니다.
... (무한 반복)
*/
return 0;
}위 예시에서 count가 2가 되면 continue가 실행되어 count++가 건너뛰어집니다.
count는 계속 2인 상태로 남아 while (count < 5) 조건이 항상 참이 되어 무한 루프에 빠집니다.
이런 경우에는 continue 전에 count++를 수행하거나, if 조건 자체를 재구성해야 합니다.
#include <iostream>
int main() {
int count = 0;
while (count < 5) {
count++; // 조건을 변경하는 코드를 continue보다 먼저 두거나,
if (count == 3) { // 3을 건너뛰는 예시 (이전 2를 건너뛰는 예시와 다름)
std::cout << "Count 3을 건너뜁니다." << std::endl;
continue;
}
std::cout << "Current count: " << count << std::endl;
}
/* 출력:
Current count: 1
Current count: 2
Count 3을 건너뜁니다.
Current count: 4
Current count: 5
*/
return 0;
}break와 continue의 사용 시점
break: 루프를 완전히 중단하고 싶을 때. 즉, 더 이상 루프 내의 어떤 반복도 필요 없을 때.continue: 현재 반복은 중단하지만, 루프 자체는 계속해서 다음 반복을 진행하고 싶을 때.
두 문장 모두 코드의 흐름을 건너뛰므로, 남용하면 코드의 가독성이 떨어지거나 디버깅이 어려워질 수 있습니다.
깔끔하고 이해하기 쉬운 코드를 작성하기 위해 꼭 필요한 상황에서만 신중하게 사용하는 것이 중요합니다.
조건의 의미를 “끝낼 조건”과 “건너뛸 조건”으로 나누면 선택이 단순해집니다.
| 찾던 값을 발견 | break로 종료 더 이상 탐색할 필요가 없으므로 반복 자체를 끝냅니다. |
|---|---|
| 잘못된 항목 발견 | continue로 제외 현재 항목만 처리하지 않고 다음 항목 검사를 이어 갑니다. |
| 무한 루프 탈출 | break가 출구 while (true) 안에서 종료 조건을 만났을 때 사용합니다. |
| 나눗셈에서 0 회피 | continue가 자연스러움 0만 건너뛰고 나머지 숫자는 계속 계산합니다. |
아래 다이어그램은 break와 continue가 루프 상태 갱신과 중첩 루프에 어떤 영향을 주는지 확인하는 제어 흐름 안전 체크리스트입니다.
흐름 제어 문장은 어디로 가는지가 아니라, 그 사이에 어떤 갱신과 정리를 건너뛰는지가 핵심입니다.
- continue
- 현재 반복의 남
문장을 건너뛴다.
- 카운터나 입력 갱신보다 먼저 나온다
- 다음 조건
이동할 갱신을 먼저 끝낸다.
- 가장 가까운 루프나 switch
끝낸다.
- 중첩 루프 전체
끝난다고 착각한다.
- 필요하면 함수 분리나 상태 플래그
범위를 드러낸다.
아래 다이어그램은 break와 continue의 도착 지점과 안전하게 쓰는 기준을 나란히 비교한 것입니다.