Getting Familiar with loops in C/C++

a2jfreaka2jfreak Houston, TX Member
edited November 2003 in Internet & Media
After Josh's IF/ELSE post I figured I'd start doing these too for anyone that just wants to dabble in C/C++ and not have to go purchase a book.

There are two main ways to loop in C/C++.
while and for. There are other ways, such as do while, goto and I'm sure some might even consider recursion to be a loop. I won't cover recursion or goto as recursion is far too involved for this brief tutorial and goto is just bad programming practice for C/C++ so I advocate not using it for looping.

The first loop structure most beginning C/C++ students are introduced to is the while loop. The syntax for the while loop is:
while (<condition>) statement;
[b]or[/b]
while (<condition>) {
    statement1;
    /// . . .
    statementN;
}

This type of loop needs to be setup, meaning that the condition variable must be initialized before entering the loop. (It is possible to use constances, but that's only advisable for infinite loops. Also, the condition variable can be initialized at first test, but this is not common practice and so it is best to avoid it for clarify.)
int keepGoing = 1;
while (keepGoing < 10) {
    ++keepGoing;  // increase [b]keepGoing[/b] by one
}

The above snippet of code has a variable of type int named keepGoing. The variable is initially set to 1, which is referred to as initializing to 1. Next we check the <condition> section of the while loop to see if it is true or false. (This is actualy like an if/else combo. If true, do the statements inside the while block, if false completely skip the while block.) Since the variable is 1, the condition is true (less than 10) and we proceed inside the while block and there is only one statement and it increases keepGoing by one. Now this is where the "looping" part comes in because unlike most areas of C/C++ code, we do not pick up and continue after the last "}." In stead, we go back to the first like of the while and check to see if keepGoing is less than 10. Since keepGoing is now set to 2, we--pun intended--keep going to the block of the while. This happens just as it did the time before and will continue to do so until the while loops through enough times for keepGoing to become not less than (read: greater than or equal to) 10, which would mean once keepGoing is set to 10 and the <condition> of the while is false (because 10 is not less than 10--they're equal) the looping will stop and the while will be exited.

The next type of looping structure we have is for. The syntax for the for loop is:
for (<initialization>; <condition>; <post-processing>) statement;
[b]or[/b]
for (<initialization>; <condition>; <post-processing>) {
    statement1;
    // . . .
    statementN;
}

The initialization is normally used the same way we used the int keepGoing = 1; statement above the while. The condition is used exactly like the condition from the while which is just like an if. The post-processing is normally used to control the loop counter(s).
for (int keepGoing = 1; keepGoing < 10; ++keepGoing);

That's it!
That's the EXACT equivalent of:
int keepGoing = 1;
while (keepGoing < 10) ++keepGoing;

However, to make them look as similar as possible (and still use them the way they're used the vast majority of the time[/b]) I will re-write them.
int keepGoing = 1;
while (keepGoing < 10) {
    ++keepGoing;
}

[b]or[/b]

for (keepGoing = 1; keepGoing < 10; keepGoing++);

Notice how the for loop didn't change? That's because it's a very compact loop. Now, once we add a bit more to the loops it will expand and start to much more closely resemble the while loop. The largest advantage the for loop has (in my opinion) is that the intialization variable(s) are only in scope for the life of the loop and since the loop counters are normally controlled incremented/decremented in the post-processing part of the for there is less chance to forget to put them which leads to fewer bugs and namely fewer infinite loops.

I have mentioned infinite loops more than once thus far so I'm sure that if you do not know what one is you're wanting to. Infinite loops are neither a good thing or a bad thing. Normally they're an undesired thing, though, but definitely not always. In fact, without infinite loops running you would not be able to read this right now--thank God for infinite loops. :D
while (1) {
  statements;
}

for (;;) {
  statements;
}

That's it. Those are both infinite loops. A bit anti-climactic, I know. There really isn't anything about them that makes them look terribly different from a normal loop. Notice though, the while has a constant--a value that never changes as the condition. Since that constant is anything except for 0 (zero) it is considered to be true. Since it never changes and it is considered true the loop never ends. The for is slightly different. It has nothing, not even a constance for its condition. I'm not exactly sure why this works, but it does and it is the standard infinite for loop. Of course, there is nothing wrong with using
for (; 1;) {
  statements;
}
if you feel the desire to have something inside the condition but it does not make a difference to the compiler (at least any that I've ever seen/used).

Now, the last type of looping structure I am going to mention is the do while. Very similar to the while loop, except for one thing--the condition is checked after the statements are executed, not before. The syntax for the do while loop is:
do {
    statements;
} while (<condition>);

So, to use the same examples I have used for both the while and the for loops for the do while I have to change very little.
int keepGoing = 1;
do {
  ++keepGoing;
} while (keepGoing < 10);

The only difference between the number of times the while will loop and the do while will loop is 1. That's because I did not change what keepGoing is initialized to. To make the loops iterate--to complete one "cycle of a loop"--the same number of times I will just change the do while ever so slightly.
int keepGoing = 0;
do {
  ++keepGoing;
} while (keepGoing < 10);

There you have it. No the while and the do while iterate through the same number of times. If it isn't apparent why they would iterate through a different number of times (had I not changed the do while) let me go through the loop to show you.
int keepGoing = 1;
while (keepGoing < 10) {
    ++keepGoing;
}

[b]and[/b]

int keepGoing = 1;
do {
  ++keepGoing;
} while (keepGoing < 10);

Just before the start of both loops we see keepGoing is initialized to 1. Once we enter the while loop we immediately check to see if keepGoing is less than 10 (and it is) and then proceed to the body of the loop. Once we enter the do while loop we immediately enter the body of the loop and increment keepGoing by 1, bringing it to 2. That, right there is why the loops iterate through a different number of times. The while goes through a whole time before 2 (the new value of keepGoing is checked against 10. The do while does not complete a whole iteration of the loop before its value of 2 is checked against it. If you believe I am mistaken, key these two separate files into your compiler.

while
#include &lt;stdio.h&gt;

int main()
{

    int keepGoing = 1;
    int keepingTrack = 0;
    while (keepGoing < 10) {
        ++keepGoing;
        ++keepingTrack;
    }

    sprintf("keepingTrack = %d", keepingTrack);
    return 0.
}

do while
#include &lt;stdio.h&gt;

int main()
{

    int keepGoing = 1;
    int keepingTrack = 0;
    do {
        ++keepGoing;
        ++keepingTrack;
    } while (keepGoing < 10);

    sprintf("keepingTrack = %d", keepingTrack);
    return 0.
}


Well, that does it. If there's anything I said I would cover and did not, just shoot me a PM or post it in this thread and I'll try to get to it as soon as possible.
Sign In or Register to comment.