Other Loops

The While loop is one of the most popular loops around, but there are other forms. We briefly mentioned the do-while loop which asks the question needed to keep looping at the end of the loop (after doing the body one time). This loop is not quite as popular, but it is there.

Remember out example where we read numbers from a user until they entered a negative number? Here is a version of that problem using a post-test loop (one that asks the question at the end!)

do {
    cin >> number;
    if (number >= 0) sum += number;
} while(number >= 0);

I have not found a large number of cases where I even use this form. In fact, it has been so long since I wrote one, I had to look it up to remember exactly how it is written in C++ (sigh!).

Note

Do you see the style I used there? If what you want to do on an IF statement, keep the then part on the same line. Another common pattern!

Counted loops

Another common looping form involves looping a specific (known) number of times.

Suppose we want a loop to process exactly 27 times. Here is a way to do that:

int count = 0;  // initialize the counter

...

while (count <= 27) {
    // do something here
    // then update the counter
    count ++;
}

Warning

This is wrong. Can you see why?

The problem with the above code is one of the most common programming errors humans make. The world famous off by one error!

By starting with zero, and going until the count is > 27, we actually loop 28 times. That is one too many. The right test would have been: while(count < 27). Of course, we could have started with count set to 1, but for a reason we will discover later, programmers always start counting from zero, not one. (I can hear it now: “I do not want to be number 1 in a line, I want to be in front of that person, I want to be number zero”. Really? Have a nice day!)

The problem with this form of counted loop is that we have to set up the question, the loop counter and add code to update the counter ourselves. Isn’t there an easier way? Sure!

The for loop

The for loop looks like this:

for(int i=0; i< 27; i__) {
    cout << "Loop pass " << i << endl;
}

Notice that I did not add code to adjust the counter value (in variable i).

The for loop works this way:

  1. A new variable named “i” in this case, is created and initialized to 0. (It could have been any value!).

  2. The check is made to see if we need to loop. In this case, the answer is yes, since i is less than 27!

  3. After the loop body has been processed, the update to the counter happens. In this case, we add one to “i”. Remember what i++ does!

Here is another example:

for (int n=5; n>0; n--) {
    cout << n << ", ";
}
cout << "FIRE!\n";

No reason why we always need to count up!

Each clause is optional

The for loop clauses are all optional. If we do not need a new variable, we can use any variable we have set up in our program that is “visible” to this point in our code. (We will go over that in more detail a bit later. For mow, that means if we defined the counter variable earlier in the same module as this statement.)

Here is what this look like:

int i = 0;

...

for(;i<0;i++) {
    cout << "loopin" << endl;
}

If we do not want to stop the loop, we do not need the conditional part in the middle spot.

int i = 0;

for(;;i++) {
    cout << "looping pass" << i << endl;
}

OMG! How do we stop this one?

We need a way to break out of a loop we ae stuck in!

Breaking out

There is a special, one word statement that gets us unstuck:

for(;;i++) {
    cout << loopint pass " << i << end;
    if (i == 27) break;
}

This will run until i has a value of 27, then stop.

The break always breaks out of the nearest enclosing loop.

We can also not do anything to the loop counter in the for loop statement itself. We will see that at work below!

Loops inside loops

This is another case of a common format. Suppose we need to create an outline format where we have five major headings, each of which has 3 minor headings. Try this:

fot(int major =1; major <= 5; major++){
    cout << "Major heading " << major << endl;
    for(int minor = 1; minor <= 3; minor++) {
        cout << "    Minor heading " << minor << endl;
    }
}

Of course, we can eliminate a few braces when we realize there is only one statement in that inner for loop.

As you can see, the counters can start with any value, have an ending condition set up, and count any way you like.

What would this do?

int j;

for(int i=0 ; ; i++) {
    cout << i;
    j = 5;
    for (;;) {
        j--;
        if (j == 2) break;
        cout << j;
    }
}

Run it to see.

That for(;;) version is a silly piece of code. It is equivalent to while(true). It also goes by the name of infinite loop (one that runs forever. Fortunately, we can use the break statement to get us out of this thing when needed!