The for Loop Structure

This Page has not been edited as yet, so take it at face value for now. It is being included because I feel so bad to have delayed these tutorials for so long and to give you more to work on this week. Check back after the next update for a corrected version (and trust me - John WILL find corrections in it! :)

Our third and final looping structure is the for loop structure. Let us take a look at the syntax:

for (expression1; expression2; expression3) {
   [statement]
}

where expression1 initializes the loop's control variable, expression2 is the conditional expression, and expression3 increments the control variable. As an example:

for (int cnt = 0 ; cnt <= 10 ; cnt++) {
    [do these things]
}

You might be able to see how this resembles while loops in certain ways. Here is the same thing in a while structure:

[...]
int cnt = 0 ;
while ( cnt <= 10) {
   [do these things]
   cnt++ ;
}
[...]

If you remember way back when I talked about naming variables, it is bad form to use a single letter as the name of a variable. Well, this is the one structure in which using only a single letter is okay (note: I said okay, not good or the right thing to do - once again, it is a matter of style). The reason this is okay is that in the for loop structure, you define your variable and use it, all inside the structure, and supposedly without the intention to use it again later. Look at this code fragment, where i is an index, or counter, value:

     for ( int i = 0 ; i <= 10 ; i++ )

After this loop completes, it should be understood that the variable i will not be used again with its' current state or value, thereby not needing a descriptive name. You can use the variable i in another for loop later, but for our purposes, i is just a counter to be used in a for loop, and nowhere else. Often, with nested loops, you will see programmers use the index counters i, j, k, ... etc - each one a level deeper in the nest, but normally starting with i.

The use of for structures are the same as while loops with only a simple counter as the conditional expression. Do a hand simulation of these two code fragments:

[...]
int data = 8;
for (int i = 0; i <= 5 ; i++)
     data += 3;
[...]

and this:

[...]
int data = 15;
int mark = 2;
for (int i = 4; i >=1 ; i--)   {
     data += 5;
     mark *=2;
}
[...]

What values to you end up with?
I decremented i in the second one, is that okay? Yes, you can decrement or increment, count down or count up. Why, you can even use the statement:

for (int i = 1, i <= 100 - someOtherVariable, i += (5*yetAnotherVariable)) 

Perfectly legal. Doesn't look to nice, and probably would cause some seriously bad logical problems, especially if the two variables were also used within the loop's structure, but perfectly legal.

I will use an example program from Deitel & Deitel's C++ How to Program book (page 93, second edition), as I cannot find one that best illustrates a good for loop in my notes right now. This one could have some use to it too, with a little modification - it calculates compound interest. Note: I took some liberties on the code, deviating from the example in the book, in order to make the display look better. It seems that BeOS has some quirks with <iomanip> that are not the same as DOS-based implementations (which seems to be the target audience of the book).


#include <iostream>
#include <iomanip>
#include <cmath>

int main()
{
   double amount = 0,                 // amount on deposit
          principal = 1000.0,         // starting principle
          rate = .05;                 // interest rate

   cout << "Year" << setw(21)
        << "Amount on deposit" << endl;

   for ( int year = 1; year <= 10; year++)   {
      amount = principal * pow(1.0 + rate, year) ;
      cout << setiosflags(ios::left) << setw (8) << year
           << setiosflags(ios::fixed | ios::showpoint)
           << setw (21) << setprecision(2) << amount << endl;
   } // end for loop

   return 0;
} // end main

I'll explain a little of what went on. First, the definitions:

   double amount = 0,                 // amount on deposit
          principal = 1000.0,         // starting principle
          rate = .05;                 // interest rate

Notice that you do not have to define each one individually, as long as they are of the same type. Placing a comma between variable declarations will define them as the same type. Indentation is not required, but recommended. You can also initialize your variables during this concatenated definition.

The cout statement here:

   cout << "Year" << setw(21)
        << "Amount on deposit" << endl;

is just sending a string of characters to the display. The setw(21) is almost like setting up columns on the display. Year is displayed in the first column (defaulting to 4 characters), and then you set up a second column 21 characters wide, where "Amount on deposit" is displayed to the right. Actually, what is happening is the program is telling the screen to display the output as 21 characters, even though the string is only 17 characters wide. The screen will add whitespace characters (spaces) to the output, thereby simulating columns or tabs.

The purpose of this example is to show a for loop in action. In the book, the purpose was also to show display formatting using <iomanip>. In the book's example, the rest of the display would have lined up nicely with the first line's "columns" that we just displayed, all right justified to the second "column". This first line worked fine in BeOS, but in the formatting of the numbers, I had a problem. The floating point numbers would not right justify in the second "column". So I modified things to look okay, not great, not how they should have been, but okay.

Now the for loop begins:

   for ( int year = 1; year <= 10; year++)   {

We define an integer variable, year, and initialize it to 1. We then check if the for loop's conditional expression is true or false, which we know to be true because we just initialized year to 1, so 1 is definitely less than or equal to 10. We then have a post-increment unary operator. That is the action that is taken on the control variable. Since this is a post increment, the value does not change until the loop's statement is completed, just before the conditional expression is checked again. Now into the loop's statement:

      amount = principal * pow(1.0 + rate, year) ;

Here we set the value in amount equal to the principal times the rate plus 1 (use 1.0 in the code since rate is a double, not an integer) raised to the power of year. The cmath library is needed to use the pow(), or power, function. The pow() function accepts two inputs, or arguments.

     pow(x, y)

The first argument (x) is the base number, and the second argument (y) is the raised power ( ). Here is the formula that was used in that statement:

     Amount = Principal x interest^years // (raised to the power of years)

I'm sure a few of you out there who are finance geeks will know this formula. If you don't, don't worry about it, it's just a mathmatical formula set to a C++ statement (it's a solution to a problem - what programming is all about, finding solutions to problems!).

Now, some io manipulation:

      cout << setiosflags(ios::left) << setw (8) << year

Here, we have told the display to show the value in the variable year at the left side of a "column" that is 8 characters wide. This is where I changed the code from the book. The code in the book was this:

       cout << setw (4) << year

but that did not work for the rest of the display. The book's version of code printed the year on the right side of the "column" that was only four characters wide. The number that displayed next, amount, would not right justify, for whatever reason, and would position itself immediately after the year on the left side of the second "column", causing the numbers to run on together and making it look like one long number. So I modified it to look better on the display.

           << setiosflags(ios::fixed | ios::showpoint)

This will insure that your floating point numbers will look like floating point numbers (showing a decimal point). BeOS will automagically format a float that has a value of 3.00 or 3.50 to display as 3 and 3.5 respectively. This is not how you want to show dollar values, so you must tell it to display the decimal, and to display do digits after the decimal, using setprecision() in this statement:

           << setw (21) << setprecision(2) << amount << endl;

Here, we tell the screen 1) to display the next output as 21 characters (unfortunately, the visible characters align left), 2) to show two positions after the decimal point (making it look and feel like dollar amounts), 3) to display the amount, and 4) to end the line.

It is at this point:

   } // end for loop

that the counter is incremented (year++), and then the conditional expression is rechecked (year <= 10). If the conditional expression is true, the loop repeats, if it is false, the program is continued on the line following the end of the loop ( } ), which in this case, returns zero and ends the program.

Here I'll also mention something that I have neglected to mention so far, the newline character ('\n') and the tab character ('\t'). The newline character does nearly the same thing as the endline command (endl), but must be used from within a character string:

        cout << "Helloworld\n" ;

The reason I had not used this in the previous examples is that endline does one more thing that the newline does not, it flushes the output buffer. Meaning, the endline will force anything that remains in the buffer to display to the screen. If you were to have used this in your first Helloworld program, it would not have displayed anything, because the program would have ended before the buffer was flushed. Your program would have appeared to not have done anything.

The reason I bring this up now is the tab character. It could be used to "make columns" in your display as well. Here, let us try it:


#include <iostream>
#include <iomanip>
#include <cmath>

int main()
{
   double amount = 0,                 // amount on deposit
          principal = 1000.0,         // starting principle
          rate = .05;                 // interest rate

   cout << "Year" << setw(21)
        << "Amount on deposit" << endl;

   for ( int year = 1; year <= 10; year++)   {
      amount = principal * pow(1.0 + rate, year) ;
      cout << year << "\t"
           << setiosflags(ios::fixed | ios::showpoint)
           << setprecision(2) << amount << endl;
   } // end for loop

   return 0;
} // end main

Notice the changes made to the way we are displaying it. We have removed the ios::left flag on the year, as well as the width of 8 in that first "column". We have also removed the width of 21 from the second "column". In all of its' place we have added the "\t" to the cout of the year value. This causes a tab to be implemented prior to displaying the value. Notice the doublequotes ( " ) around it. This is a character, and must be displayed as such. Now this runs more like what the book envisioned, but not quite the same. Looks good enough, though.

Okay, now if you have an understanding of that, go on to the next page, where I'm going to teach you one more control structure, the switch control structure, and introduce the break and continue commands. After that, we'll tie it all in together, and you will have a lot of homework to do. But for now you'll have to wait. Click Here to go back to the beginning.