We have seen that to get a computer to do what we want we must tell it every step, down to the last detail. This can be very tedious. It is especially tedious when we want it to do the same action several times. For example in the first chapter we wrote a recipe for a computer to mix a cake. We wrote "stir contents of bowl with mixing spoon 10 times". Normally, to get the computer to do this we would need 10 instructions; one for each stir. Wouldn't it be nice if we could tell the computer to repeat the previous action 9 more times? Then we could save some typing. This would be really useful especially if we had wanted the computer to stir the bowl a hundred times.
So how do we tell the computer to repeat an action many times? In the early days of computer programming, programmers would have the computer jump from place to place in the code. If you remember, programs normally execute in a downward sequence. Using the goto command programmers could force the computer to go back up when needed. Programming in this way was soon discovered to be confusing and inefficient. This method has since been replaced with a more structured method. Nevertheless, I will start by demonstrating the use of goto before I go on to explain the newer methods. So bear in mind that using goto is strongly discouraged.
The goto command works together with a label which acts as a bookmark. I first must label a certain place in my code and then I can goto that place. Here is an example:
top: cout << "Hello world!" << endl; goto top;The computer will begin reading these lines top down. When it sees the line
After this line, the computer will go on to the next line and print Hello world! to the screen one time. Then the computer will read the line
We can add a built-in method of ending the loop by adding a user interface to this code segment. The user interface will allow the user to end the loop by entering an integer, for example 0. Here is how I might do this:
bool end = 1; top: cout << "Hello world!" << endl; cout << "Press 0 to end loop, 1 to continue." << endl; cin >> end; if (end != 0) { goto top; }
Notice how I initialized the variable end with the value 1. Then I allow the user to change end's value to 0 if he desires to end the loop. Then I check if end is not equal to 0. If it is not equal to 0, I continue the loop by jumping or looping back to the top of the code section where I want the loop to start. Notice I do not loop over the initialization of end because I only need to do this line once. In addition to the initialization, the other essential part of the loop is the test condition or as it is properly called the continue condition. It is the condition by which the loop will continue looping. In this case the continue condition is
In the previous example, we allowed the user to decide when the loop will end, but sometimes we want to decide from the start how many times our loop will loop. The way this is done in general is by setting a variable to count for us. We can then repeat our action until our counter reaches some limit of our choosing. For example, if we want to do something 10 times we could set a counter to zero, and then do our action and up our counter by 1. Upping the counter by one is called incrementing the counter by one. It's called incrementing because we add the same small increment to the variable each time we loop.
Once the counter reaches 10 we know it is time to quit. You may notice that I decided to start the counter at zero, not one. This is the usual way of doing things in C++, but you could also start your counter at 1. Let's see this example first in pseudo-code and then in C++.
make a variable and call it "counter"In the above pseudo-code I gave the name "counter" to the variable, but I could have given any other name just as well. I could have called it "George", but I like to give names that mean what the variable is used for. Since this variable is supposed to count, I called it "counter." In trying to understand the logic of the above instructions ask yourself, How many times will the message "Hi mom!" get printed? Now let's see how to implement the pseudo-code in C++. Try to match up each line of pseudo-code above with the C++ below.
assign the value "0" to the "counter"
do the followingadd "1" to counter
write this message to the screen "Hi mom!"
repeat as long as counter is less than "10"
int counter;
counter = 0;
startloop:
counter = counter+1;
cout << "Hi mom!" << endl;
if (counter < 10)
{
goto startloop;
}
Can you match up the two versions? Try again!
OK, my turn to tackle this code. One thing should confuse you, what does this line mean:
"counter = counter+1;"?
How can a variable equal the same variable plus 1?
That breaks the rules of algebra! If counter is 1,
well, 1 does not equal 1 + 1! What is our mistake?
Our mistake is that we think = means equals, remember it means
assign the value on the right side to the left side.
In our case that translates to assign the value 1 + 1 to counter.
Counter had been 1, now it will be 2.
Another way of thinking about what this line means is to translate it as
follows: "the new value of counter will now be what the old value of
counter was, plus one." Think about this for a moment.
In my experience many people forget this point (if they ever really
understood it in the first place.) In any case, this is how we
increment the counter, as I explained above.
Using goto is a good way to understand how looping works, but it can get confusing especially if you have several labels. Instead of using goto we will use structured loops to create loops.
The basic structured loop is the while loop. The while loop is designed to continue some action while some condition is true. Once the condition is no longer true the while loop stops repeating. In the above example, we created the looping affect by combining the if with the goto statement. The while loop is a built-in way of combining the if with the goto. Here is the basic structure:
while ( continue condition ) { block of code }
As long as the continue condition is true, whatever is inside the braces will be repeated. As we learned earlier, I can write as many lines of code inside the braces and it will all be considered one block of code. Then this entire block of code will be repeated while the continue condition is true. Let's see the previous goto example rewritten as a while loop.
int counter;
counter = 0;
while ( counter < 10 )
{ counter = counter+1;
cout <<"Hi mom!"<<endl;
}
When the computer comes to the while keyword, it checks, is the condition true. If that condition is not true, then it skips over the block of code inside the braces, just like in an if statement, and continues to execute the code after the close brace } (in this example there is no code after the close brace, so the program would end). If, on the other hand, that condition is true then the computer begins to execute the code inside the braces { }. After the computer executes the last line inside the braces, it then comes to the closing brace }. When it sees the closing brace, it knows to jump back up to the continue condition inside the while statement. It then re-evaluates the condition and either skips or executes the block of code depending on whether the continue condition is false or true still. If the continue condition were always true, then the loop would be an infinite loop and never end. To avoid this, make sure that a variable inside the block of code is changing on each execution of the loop. In this way, eventually, the condition will be false.
In this example, the continue condition is true from the start but each subsequent loop brings counter closer to 10. When counter eventually reaches 10, the condition will be false. At that point the computer will skip the block of code and continue executing from after the close brace }. In this case, the program would finish at this point.
Some people confuse the while loop with the if statement. They are similar insofar as they both test a condition and either skip or execute the following block of code depending on whether the condition is false or true. But, the difference between while and if is that in and if statement the condition is evaluated only once and the block of code is executed at most one time. The while has the ability to repeat code by jumping up to the top again in a kind of looping effect.
In the above example we used a variable called counter and we incremented it (that is, we increased its value by one each time the loop executed). Incrementing counters or any variables is a common part of programming. Therefore, the creator of C++ made a shorter way to increment variables. Instead of writing
counter = counter +1;You can simply write:
counter++;The ++ operator (called the increment operator) is used to increase the value of the variable by one. Some people get confused and try writing
counter +1;This will in no way affect the value of counter. It is an error. So remember, if you want to write counter=counter+1, just write counter++.
If you would want to increase your counter by, say, 2 for example, you would write
counter = counter +2;But there is also a shorthand way to write this. Just write:
counter += 2;So too you can decrease or decrement your variable by one like this:
counter--;The same sort of shorthand versions of incrementing exist for the other mathematical operators also. Here is a table of some examples of incrementing and decrementing possibilities:
Long version | Short version |
i=i+1 | i++ |
i=i+7 | i+=7 |
i=i-1 | i-- |
i=i-2 | i-=2 |
i=i*8 | i*=8 |
i=i/2 | i/=2 |
There is also an alternate version of the ++ and -- operators. What you have see thus far has been of the form
variable++;You can also increment or decrement by writing
++variable;Or
--variable;How is this different from what we did previously? In the new version the incrementing or decrementing happens sooner. For example, the following code segment would print the number 8
int var1, var2; var1=8; var2=var1++; cout <<var2;This prints 8 and not 9 because the assignment to var2 happens before the incrementation of var1. If you want to force the incrememtation to happen first, you must write it like this:
int var1, var2; var1=8; var2=++var1; cout <<var2;The same is true for the -- operator. There is a simple way to remember this difference. If the ++ or -- operator appears before the variable, then the incrementation or decrementation happens before everything else. If it appears after the variable, then the incrementation or decrementation happens afterward.
We have now seen the most basic type of loop, the while loop. In truth, if you need to create a loop, all you ever really have to use is this loop. But two other loop structures exist in C++ and they are designed to be used in certain common cases.
Sometimes you may want to do a loop once no matter what and only check the continue condition statement afterward to decide whether to do the loop a second time. A classic example of this need, the need to skip the first-time condition check, is when you are printing a menu for the user. In a classic menu you want to print a series of choices for the user and then check what his response is. So we need to do the action and then check the continue condition.
I will show you the basic structure of this kind of loop and then a menu example. The loop is called a do while loop. Here is the structure:
do { code block } while ( continue condition ) ;So you see it is rather like the while loop , but in this case, the word while comes at the end. Be careful to remember the semi-colon ; at the end of the continue condition. What this structure does is execute the code block once and then test the continue condition. If the condition is true, then the code block is executed a second time, and so on.
Now let's see an example. Here is the menu example I promised:
int input;
do {
cout << "Please enter any positive integer, (-1 to quit)" << endl;
cin >> input;
cout << "You entered a " << input << endl;
}while(input != -1);
When this loop runs, it will output something like this
Please enter any positive integer, (-1 to quit) 5 You entered a 5 Please enter any positive integer, (-1 to quit) -1 You entered a -1
If I had used a while loop, I would have had to repeat code like this:
int input;
cout << "Please enter any positive integer, (-1 to quit)" << endl;
cin >> input;
cout << "You entered a " << input << endl;
while(input != -1)
{
cout << "Please enter any positive integer, (-1 to quit)" << endl;
cin >> input;
cout << "You entered a " << input << endl;
}
I think the do while version is more concise and more clear. It has also saved me some typing and potential confusions.
There is another kind of loop, the for loop. It has the advantage of compactly structuring the common commands needed for creating a loop based on a counter. Use a for loop when you know ahead of time exactly how many times you will be doing some set of actions. You will need to use and initialize a counter. Here is the structure:
for ( counter initialization ; continue condition ; counter incrementation ) { code block }
You will note that there are three sections inside the parenthesis of the for statement. They are separated by semi-colons ; . The for loop requires exactly two semicolons always. These two semicolons create three sections inside the parenthesis immediately following the word for. Any and all of these sections can be left blank. But more often you will write something in them. What you can write depends on which section you are writing in. The first section is called the initialization section. It is for setting the counter(s) you plan to use. You can also declare variables in the initalization section. The second section is called the continue condition section. It is use to set the condition by which the loop will either continue looping (iterating) or stop looping. It is the same as the continue condition of the while and do while loops. The third section is called the incrementation section. It is pretty much used for incrementing the counter, for example you may write i++ or counter++, but actually you can do just about any command here. In general, just use the incrementation section for incrememting your counter(s).
If you want to do two or more initializations or incrementations, simply separate them by commas within the relevant section. You cannot have more than one condition, but you can create complex conditions just as you can with if. So too, you can have complex conditions in the while and do while loops. Here is a basic example of a for loop (note the use of the three sections):
for ( int i = 0; i < 10 ; i++)
{
cout<<"5 times " << i <<" is " << i * 5<<endl;
}
The output of the above would be
5 times 0 is 0 5 times 1 is 5 5 times 2 is 10 5 times 3 is 15 5 times 4 is 20 5 times 5 is 25 5 times 6 is 30 5 times 7 is 35 5 times 8 is 40 5 times 9 is 45
Some other for loop possibilities are:
for ( int i = 0, int j=10 ; i < 10 && j < 100 ; i++ , j*=2) // two counters, double condition, double incrementation
for ( i = 0, j=10 ; i < 10 ; i++ , j--) // two counters, one condition
for ( i = 0 ;;) //no condition, infinite loop
for (;;) // infinite loop
You can see that the for loop allows us to include a lot of information in a concise and clear format. The for is a powerful type of loop that you can use regularly. You can use the more simple while or do while loops when you need to repeat some action an indefinite number of times.
We saw that if structures can be placed one inside the other. We called this nested ifs. The same can be done with loops. We can place a loop within another loop. We then have an inner loop and an outer loop. Doing this we create what are called nested loops. Many complex programming exercises require nesting loops. For now I will stick to some simple examples. Here is an example:
for (int i = 2 ; i < 4; i++) { for (int j = 2; j < 7; j+=2 ) { cout<<i<<'*'<<j<<'='<<i*j; cout<<endl; } }This will produce the following results:
2*2=4 2*4=8 2*6=12 3*2=6 3*4=12 3*6=18
The following example will print this:
1. 1,2,3 2. 4,5,6 3. 7,8,9Here is the example:
int number = 1; for (int i =1; i < 4; i++) { cout<<i<<'.'; for (int j =1; j < 4; j++ ) { cout<<number<<','; number++; } cout<<endl; }
This example may take you some time to understand. As you can see nested for loops can get pretty complicated. What you need to do is sit with a pen and paper and write down all the variables and keep track of how they change as the loops progress. Trying to do this in your head is asking for trouble and even experienced programmers need to resort to pen and paper when faced with complex problems such as these.
Sometimes I have a loop which can end for one of several reasons. In such a case I can use flag to indicate why the loop ended. A flag is a variable whose whole purpose is to indicate if a certain event has happened. A flag is a programming concept which can be implemented in any language. It is not specific to C++ nor is flag a reserved word. One place where I could use a flag is when, for example, I have a loop to let a person try to guess a certain number. The loop will end after 5 guesses or if he guesses the right number, which ever comes first. So how will I know why the loop ended? I can set a flag for this purpose.
int number = 75; int guess; bool gotItRight = false; // this is my flag for (int i =0; i < 5; i++) { cout<<"What number am I thinking of?" <<endl; cin >> guess; if (guess == number) { break; gotItRight = true; } } if (gotItRight) cout<<"You got it right!!" <<endl; else cout<<"No more guesses, better luck next time." <<endl;
Notice that the flag "gotItRight" will only be true if he guessed the right number. If the loop ends without his guessing the number, goItRight will still be false. There are obviously other ways to accomplish this result but using a flag is one way. Probably no program ever needs a flag, but sometimes they are convenient. But in general, try not to use flags. Never call a flag "flag". Give a flag a meaningful name, usually composed of a verb and noun.
* ***** * ***** ** **** ** **** *** *** *** *** **** ** **** ** ***** * ***** *
* *** ***** *** *
© Nachum Danzig September 2006