next up previous contents
Next: Functions Up: Getting Started in C++ Previous: Make Decisions   Contents

Subsections

Loops

Computer programs are often used for repetitive tasks: generating sequences of numbers, serving thousands or millions of web pages, and so on.

Until now, if you wanted to print the same text three times you'd have to type the same statement three times:

cout << "Hello World!\n";
cout << "Hello World!\n";
cout << "Hello World!\n";
Of course, that is not a good idea. You can do it if you need to print it out three times. But what if you had to print all the numbers from 1 to 1,000,000? Or ask the user for a list of 32 names? Or what if you didn't know how many times something has to be done as you were programming it? That's where loops come in.

A loop is a statement which repeats another statement until a condition is met. That other statement can of course be a block, or even another loop, or whatever else you wish.

while

In C++ the simplest loop is the while loop. It is used as follows:

#include <iostream>
using namespace std;

int main() {
    int i = 0;

    // Execute the loop until (i < 10) is not true
    // anymore, in other words until i >= 10
    while (i < 10) {
        // Print the number
        cout << i << " ";

        // Increase i by one
        i = i + 1;
    }
}
As you can see, while was used to repeat a block, not a single statement. That was necessary because we want it to repeat all the statements inside the block, not just a single one. It is, though, totally correct to use a single statement instead.

To give you an idea, a while loop works like this:

  1. The condition is evaluated. If it is true, execution continues in 2, otherwise the loop is ended.

  2. The statement is executed. Then execution jumps back to 1.

Thus, if the condition is false from the very beginning, the statement to repeat is never executed. For example, in

int i = 100;
while (i < 10)
    cout << i;
the cout is never executed, because i is greater than 10 from the very beginning.

do...while

The do...while loop is used as follows:

#include <iostream>
using namespace std;

int main() {
    int i;

    // Keep asking until the number is greater than 10
    do {
        cout << "Please enter a number greater than "
             << "10:"; 

        cin >> i;
    } while (i > 10);

    cout << "You entered: " << i << "\n";
}

It is very similar to the previous one, with the difference that the condition is checked at the end of the loop and not at the beginning. It is executed as follows:

  1. The statement is executed.

  2. The condition is evaluated. If it is true, execution jumps back to 1; otherwise, the loop exits and execution continues normally.

The difference between the while loop and this loop is that in the first one the statement might not be executed at all (if the condition is false from the very beginning), while in the second it is always executed at least once.

for

The for loop is the most complicated, but also the most used loop in C++. It is thus very important that you understand perfectly how it works.

The for loop is used as follows:

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 10; ++i) {
        cout << i << " ";
    }
}
As you can see, it is used like the while loop, but it takes three statements separated by semicolons.

The first statement is executed only once, before the loop starts. In this case it is used to declare and initialize the variable i, but you can do there whatever you like. The statement is not evaluated; this means that it does not matter whether it is true or not.

The second statement is the condition, which is checked (like in the while loop) before each iteration (each repetition of the statement of a loop is called an iteration); if it evaluates to false the loop is exited. In this case the condition is i < 10, thus the loop keeps iterating until i is greater or equal to 10.

The third statement is executed after each iteration. In this case it is ++i. The operator ++ increases a variable by one (increasing something by one is called incrementing); it is, in this case, the same thing as i = i + 1. (Notice that this is true in this case, but not generally; you will learn more about the difference later.)

In other words, the previous for loop is a convenient way to do the same thing as here:

#include <iostream>
using namespace std;

int main() {
    int i = 0;
    while (i < 10) {
        cout << i << " ";
        ++i;
    }
}
There is an important difference, though.

If you declare an object in the first statement in a for loop, that object is scoped to the three statements, plus the statement to repeat (the entire block if that is a block). Look at this:

for (int i = 0; i < 10; ++i) {
    // i can be accessed from here
    cout << i << " ";
} // Here i goes out of scope

// Thus, it can not be used anymore here
i = 10; // ERROR!
This is very important. It means that you can use several for loops one after another with a variable of the same name without having them clash. (Two variables clash if they share the same name and have the same scope. The compiler outputs an error message because it cannot know which variable you're referring to).

Although the for loop is mostly used in the form given above, it can be used for several other things as well. For example, you could modify the program simply using i = i + 2 to display all even numbers, or i = i * 2 for squares (you'd have to start at 1 and not at 0 to do so, though, because 0 * 2 will always be 0).

break and continue

There are two very useful statements to interrupt the normal execution of a loop: break and continue. We already know break from the switch statement; in fact it acts very similarly inside a loop. It immediately exits it and jumps to the first statement after the loop. It is generally used to prematurely exit a loop even if the loop's condition is still true.

// Let the user enter 100 positive numbers, or a
// negative number

#include <iostream>
using namespace std;

int main() {
    cout << "Enter 100 positive numbers, or a "
         <<" negative number to abort.\n";

    // Notice that here we declare i *outside* of the
    // loop. You'll see later why.
    int i;

    // Here we start counting at 1 and not at 0 because
    // otherwise the program would ask for number #0,
    // then for number #1, but we want it to start at
    // 1.
    for (i = 1; i <= 100; ++i) {
        cout << "Enter the number #" << i << ": ";
        int n;
        cin >> n;
        if (n < 0)
            break;
    }

    // If we hadn't declared i outside the loop, we
    // couldn't access it here because it'd be out of
    // scope.
    if (i == 100)
        cout << "You are a real man.\n";
    else
        cout << "You stopped after " << i 
             << " numbers, coward!\n"; 
}

The other statement, continue, is slightly more complicated but just as useful. It skips all the rest of the statements inside the loop and goes immediately to the next iteration. It is often used to skip the execution if a certain condition is met. Have a look at the following program which prints the numbers from 0 to 100 except the multiples of 7:

// Print all numbers from 0 to 100 except the multiples
// of 7.

#include <iostream>
using namespace std;

int main() {
    for (int i = 0; i < 100; ++i) {
        // Skip all the multiples of 7
        // Operator % calculates the modulo (remainder)
        // of a division; if (i % 7) is equal to zero
        // this means that i is a multiple of 7.
        if ((i % 7) == 0)
            continue;

        cout << i << " ";
    }
}
As you can see, here continue is used to skip all the multiples of 7.

Examples

The following program demonstrates the use of nested loops:

// This program prints out a multiplication table as
// follows:
// 1  2  3
// 2  4  6
// 3  6  9
//
// You could use more numbers than just from one to
// three, but then there'd be problems with the
// alignment (because there'd be numbers with one and
// with two digits).

#include <iostream>
using namespace std;

int main() {
    for (int y = 1; y <= 3; ++y) {
        for (int x = 1; x <= 3; ++x) {
            cout << x * y << " ";
        }
        cout << "\n";
    }
}

This one here is a bit more useful. It calculates factorials. (The factorial of a positive integer number $n$ is mathematically written as $n!$ and is the product of all numbers from 1 to $n$; mathematically, $n! = 1\times 2\times\ldots\times n$. So $7!=1\times
2\times 3\times 4\times 5\times 6\times 7=5040$.)

#include <iostream>
using namespace std;

int main() {
    cout << "This program calculates the factorial "
         << "of n.\n"; 
    cout << "Please enter n: ";
    int n;
    cin >> n;

    if (n < 0)
        cout << "n must be non-negative.\n";
    else {
        int factorial = 1;

        for (int i = 1; i <= n; ++i)
            factorial = factorial * i;

        cout << n << "! = " << factorial << "\n";
    }
}
The only problem here is that ints cannot hold infinitely large values (in fact, they're guaranteed to hold only values from -32767 to 32768, although generally they can hold larger values); thus if you enter too large values there will be an overflow5.1 and the output will most probably be garbage. In this specific case, the result is guaranteed to be correct only if $n\leq7$, because $8!=40320$ and is thus bigger than 32768. I'll return on this subject later.

Exercises

  1. Write a program which prints all numbers from 0 to 100.

  2. Modify the previous program to display all even numbers from 0 to 100.

  3. Now modify it to display all the odd numbers from 0 to 100.

  4. Write a program asking the user for the upper and the lower bound and then displaying all the numbers between them. It should work somehow like this:
        Lower bound: 12
        Upper bound: 23
        12 13 14 15 16 17 18 19 20 21 22 23
    

  5. Modify the previous program in a way that it asks also for the step length:
        Lower bound: 12
        Upper bound: 29
        Step size: 5
        12 17 22 27
    
    Try this program also giving it a non-positive step size. Try to find out why it locks without reading the next exercise.

  6. The previous program locks with non-positive step size because the condition never becomes false. Prevent this. The program should react as follows:
        Lower bound: 12
        Upper bound: 29
        Step size: -4
        Step size must be positive.
    

  7. Compare your program with the following one:
    #include <iostream>
    using namespace std;
    
    int main() {
        cout << "Lower bound: ";
        int lower;
        cin >> lower;
        cout << "Upper bound: ";
        int upper;
        cin >> upper;
        cout << "Step size: ";
        int step;
        cin >> step;
    
        if (step > 0) {
            for (int i = lower; i < upper; i = i + step) 
                cout << i << " ";
        }
        else 
            cout << "Step size must be positive.\n";
    }
    


next up previous contents
Next: Functions Up: Getting Started in C++ Previous: Make Decisions   Contents
Aaron Isotton <aaron@isotton.com>
2003-02-24