The syntax for the while structure is:
while(conditional expression) [statement]
In other words:
while(this is true) [do this, and repeat]
Examine the following code and comments.
#include <iostream> // STL header int main () // main function { // Begin main // Define variables for use int loop = 0; // a loop control value int data = 10; // data value // Begin the while structure while (loop <= 6) // While the value in loop is less than or equal to 6... { // Begin while data--; // decrement data by one loop++; // increment loop counter by one } // End while // Display the contents of the variables cout << "Loops = " << loop << endl; cout << "Data = " << data << endl; return 0; // Exit properly } // End main
Try and do a hand-simulation of this. Create your two variables and label them. Initialize their values.
When you get down to executing the while structure's first line, evaluate whether the conditional expression is true or false. The first time through this code, the loop variable's value is 0, so 0 <= 6 evaluates true, execute the following statement (which is within curly-braces, so it is multiple statements).
data-- ; loop++ ;
You are aware of how to hand-simulate this. Now, after the loop++; statement finishes executing, the closing while curly-brace in encountered. Because we are in a while loop, we return to the while statement and re-evaluate the conditional expression. The loop variable is now 1, the condition still evaluates true, so we execute the loop statement again. This continues until the while conditional expression evaluates to false. As soon as the conditional expression evaluates as false, the while loop ends, and the next line that is executed in the program will be the line that immediately follows the while loop statement, or in this case, the ENDING curly-brace of the while structure - the first cout statement.
Here is how the display of your hand-simulations should look:
loops = 7 data = 3 _
The underscore ( _ ) at the end is just there to show where your cursor has been left off at (the next line here because the last cout thing you did was an endline ( endl ; ).
Okay, now type the program into BeIDE and ensure that our hand-simulations prove correct. Use the filenames whiledemo.* as using the filenames while.* may cause problems with your program.
After you are done, examine this code.
#include <iostream> int main () { int mark = 1; float value = 4.2; int cnt = 1; cout << endl; // This is only to make the display look better while (mark <= 7) { value *= 2; mark += 3; cout << "Mark After: " << mark << endl; cout << "This was loop " << cnt++ << endl << endl; } cout << "I have " << mark << " and " << value << endl << "in a total of " << --cnt << " loops" << endl << endl; return 0; }
Wait a minute! I did some strange things to the variable cnt with unary operators. Why? Let's look at this in order, starting with the definition of cnt:
int cnt = 1;
I initialized cnt to 1. But the loop had not yet started, so this number is actually inaccurate, it should be zero. Now, during the first iteration of the while structure:
cout << "This was loop " << cnt++ << endl << endl;
Yes, you can have things happen within a cout statement! The variable cnt can be operated on and then printed out, killing two birds with one statement. In most cases, these things that can happen will display after they have happened. An example of this would be:
cout << cnt += 1 << endl ;
This would make cnt become cnt add 1, and then display the value.
But since cnt already had a value of 1, we need that current value to display, but we still would like to operate on it and make it increment. Remember a few lessons ago, I said that there is a big difference on the positioning of the unary operator (pre- and post-). This is where it shines. By using the post- unary operator, the value doesn't change until the entire statement has finished executing. Thus, cout will display cnt while it is a 1, and after cout has finished executing, cnt will become incremented.
Now, after the loop finishes, and the final tallies are displayed, this line should make more sense:
cout << "I have " << mark << " and " << value << endl << "in a total of " << --cnt << " loops" << endl << endl;
The value of cnt is decremented prior to displaying using the pre-decrement unary operator. Buy why are we decrementing it? Remember that we started off with a 1 in cnt, which was a number higher than we needed. And then the last iteration of the loop incremented cnt again, making it one higher than the total amount of loops conducted. Now we decrement it by one to level it back out.
Why do things this way? In all honesty, you shouldn't ever do things like this if they can be avoided. You're asking for confusion. But the reason I'm showing you this is to point out another common problem. Have you ever heard of "off-by-one" logic errors? This is where they come into play. One little mistake or miscalculation and your numbers are off by one. This is often a common problem, even among the pro's. The code displayed here is not only to show you how your numbers can easily become off by one (making cnt a 1 at initialization instead of a zero), but also how to compensate for it when it cannot be avoided in any other way. Changing the 1 to a zero at initialization would be a good (the best) way to deal with this exact code, but sometimes simple fixes just cannot be done, and you must resort to compensating the off-by-one-ness. Now you know, beware of the off-by-one pitfalls.
The comments in that code were withheld - you can figure out this one based on what you have already learned. Do a hand simulation first, and then code it into BeIDE, but code it with your own comments.
Now let's move on to something a bit more complicated before getting into for structures - nested while - if / else programs.