break와 continue
반복문들은 강력하지만, 때로는 반복 중간에 특수한 상황이 발생하여 루프의 정상적인 흐름을 벗어나야 할 필요가 생깁니다.
이러한 상황에서 프로그램의 흐름을 유연하게 제어하기 위해 사용되는 두 가지 중요한 문이 바로 break와 continue입니다.
이 두 문은 반복문(그리고 switch 문) 내에서만 사용될 수 있으며, 루프의 동작 방식을 미세하게 조정하는 데 결정적인 역할을 합니다.
break 문: 루프 즉시 종료
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: 현재 반복은 중단하지만, 루프 자체는 계속해서 다음 반복을 진행하고 싶을 때.
두 문장 모두 코드의 흐름을 건너뛰므로, 남용하면 코드의 가독성이 떨어지거나 디버깅이 어려워질 수 있습니다.
깔끔하고 이해하기 쉬운 코드를 작성하기 위해 꼭 필요한 상황에서만 신중하게 사용하는 것이 중요합니다.