# 5.8 — Break and continue

Break

Although you have already seen the break statement in the context of switch statements, it deserves a fuller treatment since it can be used with other types of loops as well. The break statement causes a do, for, switch, or while statement to terminate.

Breaking a switch

In the context of a switch statement, a break is typically used at the end of each case to signify the case is finished (which prevents fall-through):

Breaking a loop

In the context of a loop, a break statement can be used to cause the loop to terminate early:

This program allows the user to type up to 10 numbers, and displays the sum of all the numbers entered at the end. If the user enters 0, the break causes the loop to terminate early (before 10 numbers have been entered).

Note that break can be used to get out of an infinite loop:

Break vs return

New programmers often have trouble understanding the difference between break and return. A break statement terminates the switch or loop, and execution continues at the first statement beyond the switch or loop. A return statement terminates the entire function that the loop is within, and execution continues at point where the function was called.

Continue

The continue statement provides a convenient way to jump to the end of the loop body for the current iteration. This is useful when we want to terminate the current iteration early.

Here’s an example of using continue:

This program prints all of the numbers from 0 to 19 that aren’t divisible by 4.

In the case of a for loop, the end-statement of the for loop still executes after a continue (since this happens after the end of the loop body).

Be careful when using a continue statement with while or do-while loops. Because these loops typically increment the loop variables in the body of the loop, using continue can cause the loop to become infinite! Consider the following program:

This program is intended to print every number between 0 and 9 except 5. But it actually prints:

```0 1 2 3 4
```

and then goes into an infinite loop. When count is 5, the if statement evaluates to true, and the loop jumps to the bottom. The count variable is never incremented. Consequently, on the next pass, count is still 5, the if statement is still true, and the program continues to loop forever.

Here’s an example with a do-while loop using continue correctly:

This prints:

`0 1 2 3 4 6 7 8 9`

Using break and continue

Many textbooks caution readers not to use break and continue, both because it causes the execution flow to jump around and because it can make the flow of logic harder to follow. For example, a break in the middle of a complicated piece of logic could either be missed, or it may not be obvious under what conditions it should be triggered.

However, used judiciously, break and continue can help make loops more readable by keeping the number of nested blocks down and reducing the need for complicated looping logic.

For example, consider the following program:

This program uses a boolean variable to control whether the loop continues or not, as well as a nested block that only runs if the user doesn’t exit.

Here’s a version that’s easier to understand, using a break statement:

In this version, by using a single break statement, we’ve avoided the use of a boolean variable (and having to understand both what its intended use is, and where it is set), an else statement, and a nested block.

Minimizing the number of variables used and keeping the number of nested blocks down both improve code understandability more than a break or continue harms it. For that reason, we believe judicious use of break or continue is acceptable.

 5.9 -- Random number generation Index 5.7 -- For statements

### 71 comments to 5.8 — Break and continue

• Peter Baum

In the "Using Break and Continue" section with code examples is the line

The instructions are not quite right because using the enter key will not give the results that are desired.  Using say the "a" key followed by the enter key does work.

• nascardriver

Hi Peter!

Since the message asks the user to enter a character and a newline is not considered a character (by a non-coder user) I'd say the behavior is correct. You can press enter as much as you want until you enter a character.

If you want to continue when enter is pressed even without a character having been entered before you can use std::cin.peek in combination with std::cin.ignore

• Alex

Putting on my pedant hat, Peter is correct -- enter _is_ a key, and technically pressing that key by itself doesn't cause the loop to iterate. I've updated the lesson to use the word "character" instead of "key".

• Peter Baum

Under the section "Using break and continue" I see that char ch is defined within the while loop.  Could you say something about the creation and destruction of this variable each time through the while loop?  Put another way, is there an efficiency saving if the variable is created outside the while loop?

• nascardriver

Hi Peter!

For native data types (int, char, float, etc.) there is no difference between creating it inside or outside the loop. This is the case, because those data types fit into a single register (A variable that has always and will always exist and never gets constructed or destructed). So that @ch variable doesn't really exist, instead, a register will be used.
For complex data types there could be a performance difference. Classes haven't been covered yet so there's no point in trying to explain what causes this. But basically, if the class (Data type) is written properly there shouldn't be a difference here either.

• Peter Baum

There are only so many registers and different compilers and machines will do things differently.  I agree that in the simple example, there will almost certainly be no difference.  My problem is, "what in general should I do in practice if I have the goal of trying to write efficient code?"  I might very well not know where or how the code I write might be used in the future.  Wouldn't it make sense to, at least by default, try to "communicate" with the compiler by indicating that a variable should be created outside of a loop (assuming this is possible because of the program logic)?  I would think that should generally lead to more efficient code even for less optimizing compilers or situations where the compiler is struggling with lots of variables, arrays, structures, objects, et cetera.  Your thoughts on this?

• nascardriver

Scenario 1, Variable created outside of the loop, all registers are taken:
- One of the used registers will be pushed onto the stack
- Your variable uses that register
- Loop finishes, the original register is popped and restored

Scenario 2, Variable created inside of the loop, all registers are taken:
(It's the same)
- One of the used registers will be pushed onto the stack
- Your variable uses that register
- Loop finishes, the original register is popped and restored

Now you might say, "ok, it doesn't matter what I do then", wrong!
Scenario 1 leaves you with one occupied identifier (The name of the variable) that can no longer be used after the loop.

This is one of the things that the compiler knows best. So you choose the option that's better for your code, and that is, keeping your variables in the smallest scope possible.

• Peter Baum

Well, in scenario 2, it may mean pushing a register at each iteration, a significant difference from scenario 1.  Even more of a problem for larger data structures.

Regarding re-use of identifier names: that was an issue covered elsewhere.  I think it is more of what people are used to and the kind of algorithms that are tackled.  There are places for each style and the main thing is to understand the pros and cons.

• Alex

Generally speaking, it's better to optimize for limited scope, unless you discover a specific reason not to (e.g. this is a performance-critical section of code AND your compiler isn't doing an effective job of optimizing).

• Peter Baum

In the first program under "Using break and continue" would it be better to change

to something like

so you could write

so as to avoid the negation operation associated with

?

• nascardriver

Hi Peter!

There will be no negation in the compiled program. It's clearer when you write it like this:

Simplified assembly of the two versions

• Peter Baum

Thank you so much for your reply.  I see you have helped lots of people in these comment sections; your assistance is greatly appreciated.

I figured out how to disassemble code under Visual Studio and it looks like the code doesn't even use exitLoop at all.  The branch is after a compare with 'e'.

Who knows what different compilers are going to do?  What does this mean in practice for a programmer who wants to write efficient code?  My approach has been to try to "suggest" to the compiler what I can that might lead to efficiencies.  That would mean, for example, minimizing operations and using operations that I determined executed quickly.  How do you approach this issue?

• nascardriver

The compiler usually knows best. You can try to improve little things like these in code but after compilation it will most likely be the same.
If you want to gain performance you should search for loops where you might be running a needles iteration, parameters that you're passing by value even though they're of non-standard size, poorly written algorithms, and so on.
So as long as you're code in efficient when evaluating it by hand, it will be efficient when it's compiled and executed by your computer.

• Alex

Definitely. Example updated.

• nascardriver

Hi Bayar!

Great to know you didn't give up. Good job!

Here are some improvements I've made to main.cpp, if you have any questions feel free to ask.

• david

Hi Alex
in the case of nested loops can "break" and "continue" be used from inside the inner loop to terminate the outer loop?

• Alex

• nascardriver

How so?

• Alex

Sorry, I misread the question. I thought it said "inner block".

From an inner block, you can stop a loop in the outer block via continue or break.
From an inner loop, you can not use continue or break to stop the outer loop.

Thanks for pointing out my mistake.

• James Ray

Technically, the above code should be like this:

• James Ray

Am I right?

• Alex

Kinda. It's irrelevant for while loops because the end of the loop is always just a }.

I put the comment inside the loop because I thought it would make it more obvious that for a do-while loop, the condition at the end of the loop would be evaluated rather than skipped.

• David

A related question: does breaking out of a do while loop cause the condition to be evaluated?

• nascardriver

Hi David!

The condition will not be evaluated after breaking the loop.

Produces no output.

• Ethan

I think the last example about break might be a little misleading because the break happens before the last print statement meaning that the loop was terminated before executing this print statement. with the bool, when you set it to true it executes the rest of the loop THEN it terminates. these two examples are similar, but don't produce the same output. (I think. Forgive me if I'm wrong). Is this right?

• Alex

They do produce the same output (easily verifiable by running them). In the non-break case, if the user enters 'e' the rest of the loop body is skipped because it's inside an else block that does not execute for that iteration.

• bert

Typo:

This is useful (if) we want to terminate the current iteration early.

• Alex

Not if, but when! 🙂

• Max

In this program I do not understand how setting exitloop = true makes the while loop break. If bool exitLoop(false) and then in the while loop it's set to !exitLoop, wouldn't that make it true? So when it reaches the if statement exitloop = true, and wouldn't that imply that pressing "e" would keep the while loop going?
int main()
{
int count(0); // count how many times the loop iterates
bool exitLoop(false); // controls whether the loop ends or not
while (!exitLoop)
{
std::cout << "Enter 'e' to exit this loop or any other key to continue: ";
char ch;
std::cin >> ch;

if (ch == 'e')
exitLoop = true;
else
{
++count;
std::cout << "We've iterated " << count << " times\n";
}
}

return 0;
}

• Alex

Nope. Your while condition is on (!exitLoop). This means you'll keep looping as long as !exitLoop is true, which is equivalent to when exitLoop is false.

Since exitLoop starts as false, your loop will keep looping until you hit the if (ch=='e') statement and that sets exitLoop to true. At that point, !exitLoop evaluates to false, so the loop will not iterate.

• Mauricio Mirabetti

Alex, one suggestion, but please feel free to check if it's appropriate.

When explaining "continue" statement on for loops, you say:
"The continue statement provides a convenient way to jump back to the loop conditional earlier than normal, which can be used to bypass the remainder of the loop for an iteration."

Although this is true, I'd emphasize that on a for loop, continue won't jump directly to the conditional, but rather, before that, executes the "end statement". This get's clear when you explain the caveats of using continue on while and do-while.

I'd use:
"The continue statement provides a convenient way to jump back to the end-statement and loop conditional earlier than normal...".

ps.: brilliant comparison of a for loop and while construct. Simple but spot on.

• Alex

Thanks for the feedback. I've updated the definition for continue in such a way that I think will be even more intuitive.

• Darren

I disagree with the use of break in the while loop. There is probably always a way to re-organise your code to remove any break or continue usage within a loop. For example, the code in your final example could be written with a do-while construct:

Now admittedly this will print the first iteration output but it does gives you access to the character variable outside of the loop, which is something you probably want for a larger program. But arguing against my own point if break or continue do make the code easier to read, and there is no other legitimate way of doing things, then maybe they can be used. But with comments as to why.

• Alex

To me, it's cleaner to explicitly break the loop than have char ch declared outside the loop and exposed beyond it (then I have to worry about whether it does anything -- I like my variables to go out of scope as soon as they're no longer needed).

There are definitely people who share your opinion -- and the related opinion that functions shouldn't ever have an early return (only one return at the bottom). I disagree with that general philosophy. You should do whatever makes your code easiest to understand and maintain -- and often (but not always), use of break, continue, or return is the best choice for that.

• Darren

Fair point. I'm in complete agreement that code readability and code maintainability are paramount when programming.

My point was that the example you gave was contrived to read better once you'd factored in the break, that doesn't mean having a break (or continue) will necessarily make your code more clear; I think we're in agreement on that point.  In my opinion if it is logical and performant to do so an early return statement is fine so long as the intent and outcome is clear, and commented if not.

• Consider this snippet for understanding the working mechanism of 'break' statement :

int i,num;
std::cin >> num;
for(i=2;i<num;i++)
{
if(num%2==0)
{
std::cout << "a composite no.\n";
break;
}
}
if(i==num)
std::cout << "a prime no.\n";

The results on complation reflect that a single 'break' statement is able to break out two blocks at a time: the 'if' block plus the ' for' block.

I was expecting the break statement to work only for the inner block-the 'if' block and not for the 'for' block along with.

• Alex

Yes, thanks for pointing this out. As the lesson says:

> The break statement causes a do, for, switch, or while statement to terminate.

If statements don't count. And as you've noticed, break works even if you're in an inner block.

• Nyap

> This includes the for each loops included in C++11.
we never covered those?

• Alex

Yeah, that used to be covered in chapter 5, but I moved it to chapter 6. I've removed the comment.

• Why not? 'break' in any block, not only loop and switch.....

• Alex

I'm not sure why C++ doesn't support this, as there are certainly cases where it would be useful to break out of any arbitrary block. There are a number of workarounds but none of them are great, as they obfuscate the intent of the programmer.

• coprog2

how to stop a running while loop. while running from 1-100. i need to stop at 20 by just pressing a key.
Ex. output:
int x=0
while(x<100){
_sleep(1000);
cout<<x++<<endl;}

• Alex

There is no way that I'm aware of to do this in standard C++. A library like ncurses might be able to do something like this.

• required

this program prints
0 1 3 2 4 6 7 8 9 as well
just wanted to mention. please don't call me arrogant. 🙂

• Alex

I'm confused. How would this program print 0 1 3 2? It only uses ++, so it's not possible for it to decrement.

With erroneous output he claimed the program printed, I'm guessing now we can call him "arrogant!" LOL!

• Louis

how can I turn back to the begining after the last case of switch?

• Alex

You want the switch to execute again? If so, put it inside of a loop.

• Louis

I did but after the last case, it's stop...

• Alex

I'd have to see your code to determine what's not working.

• Elpidius

Typo in the second-to-last paragraph:
"... understand what both what its intended use is ..."
One of the words, "what", should be removed.

• Alex

Fixed. Thanks!

• // continue loop example
#include<iostream>
using namespace std;

int main()
{
for (int n=10; n>0; n--) {
if  (n==5) continue;
cout<< n << " , ";
}
cout <<"FIRE!\n";
return 0;
}
WHAT IS THE OUTPUT?
I'm having a difficult time running it what's the problem with my program, thanks

• Keith

This won't compile. Try replacing the n- in the for statement with n-- or better still, --n, so it reads

The expression n- doesn't mean anything, it is the subtraction operator, so it is expecting you to provide another value to subtract from n. What you want is the decrement operator, n--.

Once you've changed this, the output should be 10 , 9 ,  8 , 7 ,  6, 4 , 3 , 2 , 1 , FIRE!

• Shiva

Buddy, I think it is a problem with the comment formatter or something of this site, because your comment too is showing 'n-' where you intended 'n - -'. I've seen it in other comments too. Even Alex seems to be experiencing such issues (with angle brackets, IIRC).

It would be safer to put all our code inside the syntax highlighter using the [code] tags, which displays them alright. To type bits and pieces, there seems to be no other way than tweaking them (without affecting the intended meaning) as I've done above.

Hope this helps someone.

• In th "continue" section of this chapter, the first code sample is broken.
In line 8, "iii" should be "count"

• Alex

Thanks!

• Sorry...
In my suggestion,

should be:

• A suggestion. In Break vs Return section, you can write the example like this:

Correct me if I am wrong. I found this easier to understand. It may not.

• Alex

I think this does help clarify the intent of each. I've updated the example accordingly.

• Niranjan

Hi Alex,
Really great tutorial. However I am one of those people who is just revisiting c++ to brush up the skills and avoiding the pitfalls. I think what would be great is if you can add a small box (with an icon indicating danger) around text items where you give advice about dangers and common mistakes. That way it is easy for people like me to browse through this faster and for newbs to remember.

Thanks

• Alex

Good idea. I'll look into it.

• cpplx

mine will be about the use of the term "program" for a snippet
and the usage of post(blah++) instead of pre(++blah) increment.
minor things but they confuse me as a beginner in what is the proper way.

• Alex

Also fixed, I think.

• Todd

Typo.

In the first block of code you reference, all your function names begin with a capital letter (e.g., DoAddition), but these should begin with a lowercase letter by naming conventions (e.g., doAddition)

• Alex

Fixed.

• A suggestion for a useful coding style:

When using break and/or continue in loops, try to have them either right at the start or end, preferably at the start, so they are easy to spot and thus keeping the control flow easy to read.

Another suggestion, wouldn't having a chapter about understanding the flow of the loops be appropriate? I'm mostly thinking of things like is there an invariant (eg. int count tells us which numbers has been printed so far) and are there any termination conditions, so the loop can actually terminate. And also as you touch upon with the continue are there any control flow that can make the termination condition(s) inaccessible.

• DrSuse

Considering this little snippet:
``` int iii=0; while (iii < 10) { if (iii==5) continue; cout << iii << " "; iii++; } ```
Is there any elegant way to make this work as intended as a "while" function?
If you put the increment (iii++) before the if, then "0" never gets printed. The only way I know to get "0" included in the output this way is to initialize iii as -1, which seems like a very sloppy way to do things.
You could replace "continue;" with an "iii++" and get the desired result, , but I would like to see how this could be done, simply and elegantly, using the "continue" statement.

``` int iii=0; while (iii < 10) { if (iii==5) { iii++; continue; } cout << iii << " "; iii++; } ```

• Alex

This works but is somewhat inelegant, since you have two places where the loop variable can get incremented.

Personally, I'd use a for loop, because a for loop will always increment the loop variables even if continue is used.

You could also invert the logic:

• Najla

Thank you so much, that was very helpful to me.