Monday, January 17, 2011

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 switch statement, while loop, do while loop, or for loop to terminate. 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):
01switch (chChar)
02{
03    case '+':
04        DoAddition(x, y);
05        break;
06    case '-':
07        DoSubtraction(x, y);
08        break;
09    case '*':
10        DoMultiplication(x, y);
11        break;
12    case '/':
13        DoDivision(x, y);
14        break;
15}
In the context of a loop statement, a break can be used to cause the loop to terminate early:
01#include <cstdio> // for getchar()
02#include <iostream>
03
04using namespace std;
05
06int main()
07{
08    // count how many spaces the user has entered
09    int nSpaceCount = 0;
10
11    // loop 80 times
12    for (int nCount=0; nCount < 80; nCount++)
13    {
14        char chChar = getchar(); // read a char from user
15
16        // exit loop if user hits enter
17        if (chChar == '\n')
18            break;
19
20        // increment count if user entered a space
21        if (chChar == ' ')
22            nSpaceCount++;
23    }
24
25    cout << "You typed " << nSpaceCount << " spaces" << endl;
26
27    return 0;
28}
This program allows the user to type up to 80 characters (the standard length of a console line). If the user hits enter, the break causes the loop to terminate early.
Note that break can be used to get out of an infinite loop. The following program loops until the user hits enter:
1while (1)
2{
3    char chChar = getchar();
4    if (chChar == '\n')
5        break;
6}
Continue
The continue statement provides a convenient way to jump back to the top of a loop earlier than normal, which can be used to bypass the remainder of the loop for an iteration. Here’s an example of using continue:
1for (int iii=0; iii < 20; iii++)
2{
3    // if the number is divisible by 4, skip this iteration
4    if ((iii % 4) == 0)
5        continue;
6
7    cout << iii << endl;
8}
This program prints all of the numbers from 0 to 19 that aren’t divisible by 4.
Be careful when using continue with while or do while loops. Because these loops typically iterate the loop variables in the body of the loop, using continue can cause the loop to become infinite! Consider the following program:
1int iii=0;
2while (iii < 10)
3{
4    if (iii==5)
5        continue;
6    cout << iii << " ";
7    iii++;
8}
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 iii is 5, the if statement is true, and the loop returns back to the top. iii is never incremented. Consequently, on the next pass, iii is still 5, the if statement is still true, and the program continues to loop forever.
Using break and continue
Many textbooks caution readers not to use break and continue because it causes the execution flow to jump around. While this is certainly true, judicious use of break and continue can actually help make loops much more readable. For example, the following program prints all numbers from 0 to 99 which are not divisible by 3 or 4, and then prints out how many numbers were found that meet this criteria:
01int nPrinted = 0;
02
03for (int iii=0; iii < 100; iii++)
04{
05    // messy!
06    if ((iii % 3) && (iii % 4))
07    {
08        cout << iii << endl;
09        nPrinted++;
10    }
11}
12
13cout << nPrinted << " numbers were found" << endl;
However, this can be rewritten as the following, which is easier to read:
01int nPrinted = 0;
02
03for (int iii=0; iii < 100; iii++)
04{
05    // if the number is divisible by 3 or 4, skip this iteration
06    if ((iii % 3)==0 || (iii % 4)==0)
07        continue;
08
09    cout << iii << endl;
10    nPrinted++;
11}
12
13cout << nPrinted << " numbers were found" << endl;
Keeping the number of nested blocks down often improves code readability more than a break or continue harms it. For that reason, your author is generally in favor of using break and continue when and where it makes the code easier to understand.

No comments: