C++ Break and Continue
Sometimes you don’t want a loop to run through every single iteration in the normal way. Maybe you found what you were looking for and want to stop early, or maybe you want to skip just one iteration without ending the whole loop. C++ gives you two keywords for exactly this: break, which exits a loop immediately, and continue, which skips the rest of the current iteration and jumps to the next one. Together they let you write loops that react to conditions discovered while they’re running, instead of loops that blindly run to completion.
Overview / How It Works
break and continue are jump statements. When the compiler generates machine code for a loop, it produces a block of instructions with a condition check, a body, and (for for/while) an update step, all wired together with conditional and unconditional jumps. Normally, execution flows from the top of the loop body to the bottom, then back up to re-check the condition. break and continue insert an extra jump instruction at the point they appear:
- break generates a jump straight to the first instruction after the loop entirely. The loop’s condition is never checked again — the loop is abandoned immediately, as if it had naturally finished.
- continue generates a jump to the loop’s update/condition-check step. In a
forloop, that means the update expression (likei++) still runs, then the condition is tested again. In awhileordo-whileloop, it jumps straight to the condition test, skipping any code aftercontinuein the loop body — including any manual counter updates you wrote there.
Both statements only affect the innermost enclosing loop (for, while, or do-while). If you have loops nested inside each other, a break or continue in the inner loop has no direct effect on the outer loop — the outer loop just sees its inner loop finish (via break) or continue looping (via continue) as normal. This is one of the most common sources of confusion for beginners, and we’ll walk through it in detail below.
break is also used inside a switch statement to stop execution from falling through to the next case — that’s a different, unrelated use of the same keyword, but the underlying idea (jump out of the current block) is the same.
Syntax
for (initialization; condition; update) {
if (someCondition) {
break; // exits the loop immediately, skips update and condition check
}
if (otherCondition) {
continue; // jumps to 'update', then re-checks 'condition'
}
// rest of the loop body
}
| Statement | Effect | Where it can appear |
|---|---|---|
break; |
Immediately terminates the nearest enclosing loop or switch. No further iterations run. |
Inside for, while, do-while, or switch |
continue; |
Skips the rest of the current iteration’s body and moves to the loop’s update/condition check. | Inside for, while, or do-while only |
Examples
Example 1: Using break to stop searching once found
A very common pattern is searching for something and stopping as soon as it’s found, instead of wasting time checking every remaining value.
#include <iostream>
using namespace std;
int main() {
int found = -1;
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 7 == 0) {
found = i;
break;
}
}
cout << "First number divisible by both 3 and 7: " << found << endl;
return 0;
}
Output:
First number divisible by both 3 and 7: 21
The loop checks numbers 1 through 100 in order. As soon as i equals 21 (the first number divisible by both 3 and 7), the break statement fires. Execution jumps straight out of the for loop, so numbers 22 through 100 are never even examined. Without break, the loop would keep running (and possibly overwrite found with 42, 63, or 84 later), so break is what guarantees we keep the first match.
Example 2: Using continue to skip unwanted values
continue is useful when you want to filter out certain iterations without writing deeply nested if blocks.
#include <iostream>
#include <string>
using namespace std;
int main() {
string word = "programming";
string consonantsOnly = "";
for (char c : word) {
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
continue;
}
consonantsOnly += c;
}
cout << "Original: " << word << endl;
cout << "Consonants only: " << consonantsOnly << endl;
return 0;
}
Output:
Original: programming
Consonants only: prgrmmng
This uses a range-based for loop to visit every character of word. Whenever the character is a vowel, continue immediately jumps to the next iteration, skipping the line that appends the character to consonantsOnly. Consonants fall through to the append line normally. The result is a string with every vowel removed, built without a single else branch.
Example 3: break only exits the innermost loop
This example combines both keywords in nested loops and shows exactly how far break reaches.
#include <iostream>
using namespace std;
int main() {
int target = 12;
bool foundPair = false;
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (j % 2 == 0) {
continue; // skip even j values
}
if (i * j == target) {
cout << "Found pair: " << i << " * " << j << " = " << target << endl;
foundPair = true;
break; // only exits the inner (j) loop
}
}
if (foundPair) {
break; // now exit the outer (i) loop too
}
}
if (!foundPair) {
cout << "No pair found." << endl;
}
return 0;
}
Output:
Found pair: 4 * 3 = 12
The inner loop only tries odd values of j (1, 3, 5) because continue skips even ones. When i = 4 and j = 3, the product equals 12, so the inner break fires and exits only the j loop. Control returns to the outer i loop, which checks the foundPair flag and calls its own break to stop entirely. This two-flag pattern — a boolean plus a second break in the outer loop — is the standard idiom for exiting nested loops in C++, since C++ has no built-in “break out of two loops at once” keyword (unlike some other languages).
How It Works Step by Step
- For break: the CPU is executing instructions inside the loop body. When it reaches the
break, it performs an unconditional jump to the instruction address immediately following the loop’s closing brace. The loop’s condition variable and update step are never touched again for this loop. - For continue in a for loop: execution jumps to the update expression (e.g.
i++), which still runs, and then the condition is re-evaluated as usual. This is whycontinueis generally safe insideforloops — the counter always gets updated. - For continue in a while/do-while loop: execution jumps directly to the condition check (or, for
do-while, to the bottom condition test). There is no separate “update” step in awhileloop’s syntax, so any counter increment you wrote after thecontinuein the body gets skipped. You must place counter updates before the point wherecontinuecan trigger, or the loop variable will never change. - Nested loops: each loop has its own, independent jump targets. A
breakorcontinuealways resolves to the nearest loop that textually encloses it — the compiler doesn’t look further out.
Common Mistakes
Mistake 1: Expecting break to exit all nested loops
Beginners often assume a single break will exit every loop it’s nested inside. It doesn’t — it only exits the innermost one.
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (j == 2) {
break; // only exits the inner (j) loop
}
cout << "i=" << i << " j=" << j << endl;
}
}
return 0;
}
Output:
i=1 j=1
i=2 j=1
i=3 j=1
A programmer expecting the whole nested loop to stop after the first break would be surprised to see it print three lines, once for each value of i. The fix, as shown in Example 3, is to use a boolean flag (or a function with an early return) so the outer loop can decide to stop too.
Mistake 2: continue skipping a manual counter update in a while loop
This is a classic cause of infinite loops. If the increment sits after the continue, it never runs for the skipped iterations.
#include <iostream>
using namespace std;
int main() {
int i = 0;
while (i < 10) {
if (i % 2 == 0) {
continue; // BUG: jumps to the condition check, i++ below never runs
}
cout << i << " ";
i++;
}
return 0;
}
Because i starts at 0, which is even, continue fires on the very first pass and jumps back to the condition check — but i is still 0, so the condition is true again, and this repeats forever. This snippet is shown for illustration only; running it would hang. The fix is to move the counter update to before the continue can trigger:
#include <iostream>
using namespace std;
int main() {
int i = 0;
while (i < 10) {
i++;
if (i % 2 == 0) {
continue; // skip evens; i was already incremented above
}
cout << i << " ";
}
cout << endl;
return 0;
}
Output:
1 3 5 7 9
By incrementing i first and testing the skip-condition second, every iteration guarantees forward progress, so the loop is guaranteed to terminate.
Best Practices
- In
whileanddo-whileloops, always update your loop counter before anycontinuestatement that could skip it, to avoid accidental infinite loops. - When you need to break out of nested loops, use a boolean flag checked after the inner loop, extract the loops into a separate function and
returnearly, or restructure the logic so a single loop with compound conditions suffices. - Avoid overusing
breakandcontinueas a substitute for clear conditions — a loop with one obvious exit condition is often easier to read than one riddled with early exits. - Use
continueto keep loop bodies flat: skip invalid or uninteresting values at the top, rather than wrapping the rest of the body in a largeifblock. - Remember
breakalso affectsswitchstatements written inside a loop — abreakinside aswitchcase only exits theswitch, not the loop around it. - Comment non-obvious uses of
break/continue, especially in nested loops, since the scope they affect isn’t always visually obvious.
Practice Exercises
- Exercise 1: Write a program that prints all numbers from 1 to 50, but stops printing entirely (using
break) as soon as it reaches a number greater than 30 that is also divisible by 6. - Exercise 2: Write a program that loops through the numbers 1 to 30 and uses
continueto skip any number divisible by 3 or 5, printing all the others. Hint: the first few numbers printed should be 1, 2, 4, 7, 8. - Exercise 3: Write a program with a nested loop (outer 1–5, inner 1–5) that searches for two numbers whose sum equals 9. Use
continueto skip pairs where either number is even, and use a flag plusbreakin both loops to stop as soon as the first valid pair is found. Print the pair.
Summary
breakimmediately exits the nearest enclosing loop (orswitch), skipping any remaining iterations.continueskips the rest of the current iteration and jumps to the loop’s update/condition check, without ending the loop.- In a
forloop,continuestill runs the update expression before re-checking the condition; in awhile/do-whileloop it does not run any code after it, which can cause infinite loops if a counter update is placed aftercontinue. - Both statements only affect the innermost loop they’re written in — a flag variable or early
returnis needed to exit multiple nested loops at once. - Used well,
breakandcontinuemake loops read more naturally by handling special cases (early exit, skipped values) without deeply nested conditionals.
