Section 5 - Exiting Loops

4A.5.1 Exit Using Break

So far, we have seen that a loop is a collection of statements that gets executed over and over until a certain bool condition in the loop control becomes false (or an int expression becomes 0).  Sometimes it is convenient, however, to have an alternate way to leave the loop.  We may, for instance, find ourselves suddenly compelled to exit a loop while we are still deep in the middle of the loop body.

Let's start by looking at alternative ways to exit from for, while or do/while loops.

The break statement can be used to exit from a loop from anywhere inside its body.

As an example,  say we are in a large loop body, and we ask the user for a response. If the user types a 'q', they want out immediately.

#include <iostream>
#include <string>
using namespace std;

int main()
{
string response;
int balance = 1000;

while( balance > 0 )
{
// lots of statements, then...

getline(cin, response);

// if response is "quit" user wants out!
if ( response[0] == 'q' || response[0] == 'Q' )
break;

// lots of other statements 
// ... 
}
}

Notice that the loop has some overall condition that is easy to understand in the while loop control:  balance > 0.  Meanwhile, during the processing of the loop we get input from the user that may indicate his wish to end the loop (by typing of "Q" or "quit", etc.).  The point is, that we don't want to do the remainder of that particular loop pass if response is "quit", nor do we want to do any other loop passes. Therefore we test for the quit response and if we find it, we issue a break statement that gets us out of the loop instantly. 

Do you remember that response[position] is an individual char from the string?  Here we are testing the first char in the string - that is, the first letter of the word the user typed.  Why do we use 0 for position instead of 1?

4A.5.2 Break is a Valid Structured Programming Statement

There are some programming authors or teachers who have the misguided view that there is something wrong with break statements.  This is absolutely untrue and you need to be ready to answer their view (which is regurgitated from their instructors, without careful consideration).  So, I'm going to help you win this argument, once and for all.  (This will be good at your next programming cocktail party!).

How would they solve the problem of exiting the above loop, mid loop body,  if they did not use the break statement?

There are really only two ways:

  1. Place the remainder of the loop body ( i.e, the statements after the getline() method call) in a large if body, controlled by
if ( response[0] == 'q' || response[0] == 'Q' )
  1. Incorporate a test for response[0] == 'q' somewhere in the while control, as in:
while ((balance > 0) && (response[0] != 'q') && (response[0] != 'Q'))

Workaround 1 is ugly because it would require indenting the entire remainder of the loop body controlled by the if, making it look in some way subordinate to the upper part of the loop body:

while ( <condition> )
{
<statement>;
<statement>;
<statement>;
if ( response != "quit" )
{
<statement>;
<statement>;
<statement>;
}
}

As you can see, this gives an incorrect impression about the flow of the loop since the statements below are of equal importance and scope as the ones above.

Workaround 2 is problematic because the condition

(response[0] != 'q' ) && (response[0] != 'Q' )

may be unrelated to the principal condition for the loop, namely the balance being positive, and thus create a long condition which is unnecessarily hard to understand.   Of equal importance,  you would have to force an unnatural value into response before the loop begins to get it past this test (like response = "OK").

These are important issues, not just for motivating the break statement next, but for your general education. You need to learn how to evaluate choices in C++, since there are always many ways to do the same thing. By letting you see the thought process behind our need for break, even though we can do without it, you will come to make the correct choice in other situations.

In some programs, you might even see this:

while (true)   /* forever */
{
<statement>;
<statement>;
<statement>;
<statement>;
if ( <condition> )
break;
<statement>;
<statement>;
<statement>;
<statement>;
}

In this code, the programmer could not find a way to test near the beginning or end of the loop, so the exit condition had to appear in the middle. Therefore, while it looks like an infinite loop  there is an escape in the form of a break.

4A.5.3 Skipping the Current Loop Pass with Continue

There are times when you want to stay in the loop, but skip past the remainder of the statements in the body for just the current pass. This is done with a continue statement:

while ( <loop condition> ) 
{
<statement>;
<statement>;
<statement>;
<statement>;
if ( <skip condition> )
continue;
<statement>;  // if <skip condition> is true
<statement>;  // all these lines will be
<statement>;  // skipped for this one
<statement>;  // pass
}

As soon as the continue is reached, control will pass back to the top, and the <loop condition> will be evaluated for possible termination.

Caution

break and continue are not the correct way to deal with mutually exclusive decision choices (like different age brackets or distinct animals). The proper way to handle mutual exclusivity is consecutive else if statements, not loops.

decorative flower