The for Loop Statement

   


The for Loop Statement

As we have seen in many previous examples involving iteration, the three key components of a loop are as follows:

  • Loop condition When evaluated to true, will cause the loop body to be repeated.

  • Loop initialization During the loop initialization the variable(s) taking part in the loop condition are assigned initial suitable values. This process only takes place once before the loop commences.

  • Loop update Updates the variables of the loop condition. This is repeatedly done during every loop.

These are exemplified in Figure 9.6, which uses the source code of the while loop shown earlier. Notice that only the loop condition is restrained by the rules of syntax to a specific position, namely inside a pair of parentheses positioned right after the while keyword. On the other hand, the loop initialization and loop update can be positioned anywhere. This is fine for a simple loop with a small loop body, such as the one shown here, but if initializations and updates are scattered around large amounts of code, it can become difficult to locate and remain conscious about these loop hotspots. All too often, this results in while or do-while loops that, during alterations, only have one or two key components modified without the necessary adjustments for the third components.

Figure 9.6. The three key components of a loop.
graphics/09fig06.gif

The for loop addresses this potential problem by providing exact syntactic rules for the location of all three loop control elements. As Syntax Box 9.3 shows, all three elements must be enclosed in parentheses next to the for keyword and separated by semicolon.

Syntax Box 9.3 The for-Loop Statement

 for ( [<Initialization_statements>] ; [<Loop_condition>] ;  graphics/ccc.gif[<Update_statements>] )       <Loop_body> 

where:

 <Loop_body>::= <statement>;            ::= <Compound_statement> <Initialization_statements>::= <Initialization_statement1>,                               <Initialization_statement2>... <Loop_condition>::= <Boolean_expression> <Update_statements>::= <Update_statement1>,  graphics/ccc.gif<Update_statement2>... 

Note:

  • Use commas, as shown, to separate more than one initialization statement. The same applies if more than one update statement is specified. Semicolons are used to separate the loop statements from the loop condition and the loop condition from the update statements.

  • The initialization statements, along with the loop condition and the update statements, are all optional. Consequently

     for ( ; ; ) {     // do something } 

    constitutes a valid for-loop. Notice that the two semicolons must still be included.

The syntax of the for loop allows us to implement the same semantics as the code of Figure 9.6. This is done in Figure 9.7. It is important to notice that the timing of events taking place in the for loop are the same as those of the displayed while loop, which means

  • The loop initialization takes place only once on entry to the loop.

  • The loop condition is evaluated at the beginning of each iteration.

  • The loop update is performed at the end of each iteration.

Figure 9.7. A for loop and its corresponding while loop.
graphics/09fig07.gif

Note

graphics/common.gif

The for and while loop constructs are both entry condition loops. The do-while loop is the only exit condition loop in C#.


Note

graphics/common.gif

The loop body of the for statement can, like that of the while and do-while loops, be either a single or compound statement. The three different loop constructs are always counted as a single statement, disregarding the number of statements it contains in the loop body.


The following discusses the implications of the notes written in Syntax Box 9.3.

1. Each of the three loop parts in the for loop is optional, however the parentheses after the for keyword must always contain three semicolons.

Example: Figure 9.7 showed us how a while loop can be converted to fit into the conventional framework of a for loop. Conversely, Figure 9.8 illustrates how the for loop can mimic the syntax of the while loop, the only difference being the for keyword and a couple of semicolons. The loop initialization index = 0 of the for loop has been removed from its position inside the parentheses to line 2, and the loop update index++ removed to line 6.

Figure 9.8. for loop looking like a while loop.
graphics/09fig08.gif

It is even possible to omit the loop condition and leave the parentheses empty apart from the obligatory semicolons. A missing loop condition is interpreted by the compiler to be a loop condition that is always true, making for( ; ; ) equivalent to for( ; true; ). The following would thus constitute an infinite loop:

 for (   ;   ;  ) {     Console.WriteLine("I'm repeated infinitely many times"); } 

Notice that the following while and do-while statements also constitute infinite loops:

 while(true) {     Console.WriteLine("Pyyyhhhh, this is hard work"); } do {     Console.WriteLine("As spoken out of my mouth"); } while (true) 

You might, with good reason, wonder if a loop condition that is always true has any practical use. It turns out that it can be used together with the break statement you already met during the switch statement discussion, but more about this later in the section "The Jump Statements break and continue".

2. The loop initialization and loop update can consist of several statements separated by commas, but only a maximum of one loop condition is permitted.

Because of this, it is possible to include as many initializations and updates as you want within the parentheses after the for keyword.

The program in Listing 9.4 utilizes this feature to determine a number positioned between the initial values of i and j (in this case 0 and 21) for which it is true that it is one third from i towards j (and two thirds from j towards i). The loop body of the for loop prints the values of i and j as they get closer to the solution. In this case, the answer is 7, as shown in the final line of the sample output.

Listing 9.4 OneThird.cs
01: using System; 02: 03: class OneThird 04: { 05:     public static void Main() 06:     { 07:         int i; 08:         int j; 09: 10:         Console.WriteLine("Value of\n i   j\n"); 11:         for (i=0, j=21; i <= j; i++, j=j-2) 12:             Console.WriteLine(" {0}    {1} ", i, j); 15:     } 16: } Value of  i    j 0    21 1    19 2    17 3    15 4    13 5    11 6    9 7    7 

Line 11 specifies the for loop to enclose two initialization statements (i = 0 , j = 21) and two update statements (i++ , j = j - 2), in each case separated by the comma operator (see the following Note), whereas the loop body of line 12 merely performs a simple printout. Because j is decremented by 2 every time i is incremented by 1, i will be greater than j, and will make the loop condition i <= j false, approximately when i is one third toward the original value of j and j is two thirds towards the original value of i.

The Comma Operator

graphics/common.gif

The language element allowing us to squeeze two or more expressions into the space of one for statement is called the comma operator. The effect of the comma operator, as in the following

 for (i=0, j=21; i <= j; i++, j=j-2)   //combining i=0, j=21 and                                       //combining i++ and j=j-2 

is to combine two or more statements to count as one and, hence, fit where just one statement is expected.

The comma operator should not be confused with:

  • The role the comma plays in a declaration statement, such as

     int count, distance; 

    where it is used to separate the two variable identifiers that are declared to be of type int.

  • Its use as a separator for formal parameters in a method header:

     public static int Sum(int a, int b) 
  • The separation of method arguments in a method call

     Sum(10, 20); 

    Notice that instead of declaring i and j in lines 7 and 8 of Listing 9.4, it is possible to declare them inside the for statement as part of the initialization, as in the following:

     11:         for (int i=0, j=21; i <= j; i++, j=j-2) 

    According to the scope rules discussed previously, the scope of i and j is then confined to that of the loop body of the for loop, which is acceptable because i and j are only used within this scope.

    The compiler can confuse the comma operator and the comma separator, so it is not possible to separate two variable declarations (they contain the comma separator) with the comma operator, as shown next.

     11:         for (int i=0, int j=21; i <= j; i++, j=j-2)  //Invalid 

    The left most comma can either be a comma separator or a comma separator, the compiler has no way of telling which one it is.


Note

graphics/common.gif

You can only have a maximum of one loop condition in the for statement, but because the loop condition is a Boolean expression, you can still use the logical operators (&&, ||, !, &, |, ^) to form longer Boolean expressions.


Tip

graphics/bulb.gif

Only use the loop initialization and loop update for variables that are part of the loop condition.

The comma operator allows you to insert an infinite number of expressions into the space of the loop initializations and loop updates. It can be tempting to cram initializations and updates in here other than those directly linked to the variable(s) of the loop condition. Listing 9.5 illustrates this. It creates a table of heights and widths and, for each pair, calculates the resulting area.


Listing 9.5 AreaCalculatorUgly.cs
01: using System; 02: 03: class AreaCalculator 04: { 05:     public static void Main() 06:     { 07:         int i; 08:         int width; 09:         int height; 10: 11:         Console.WriteLine("height   width     area\n"); 12:         for (height = 1000, width = 100, i=0; i <= 10; 13:             height = height + 100, width = width + 10, i++) 14:         { 15:             Console.WriteLine("{0}      {1}       {2} ", 16:                 height, width, height * width); 17:         } 18:     } 19: } height   width      area 1000     100      100000 1100     110      121000 1200     120      144000 1300     130      169000 1400     140      196000 1500     150      225000 1600     160      256000 1700     170      289000 1800     180      324000 1900     190      361000 2000     200      400000 

Note that lines 12 and 13 not only contain the loop initialization and loop updates for the loop condition variable i, they also contain initializations and updates for width and height. Consequently, the only thing left for the loop body to do is to print out the values calculated in the loop initialization and updates. Notice that it becomes hard to distinguish between the elements dealing with the control of the loop (the variable i) and those that are merely part of the processes performed during each loop. The ability and advantage of the for statement to enable a separation between the loop controlling parts and other processes performed during one loop has been misused, resulting in cluttered, unclear, ugly code. Listing 9.6 shows an improved version with exactly the same functionality as Listing 9.5.

Listing 9.6 AreaCalculatorImproved.cs
01: using System; 02: 03: class AreaCalculator 04: { 05:     public static void Main() 06:     { 07:         int i; 08:         int width; 09:         int height; 10: 11:         height = 1000; 12:         width = 100; 13:         Console.WriteLine("height   width     area\n"); 14:         for (i=0; i <= 10; i++) 15:         { 16:             Console.WriteLine("{0}      {1}       {2}", 17:                 height, width, height * width); 18:             height = height + 100; 19:             width = width + 10; 20:         } 21:     } 22: } 

The output is the same as that from Listing 9.5.

The initializations and updates of height and width have been removed from the pair of parentheses following the for keyword. The initializations have been put in lines 11 and 12 prior to the for statement, and the updates have become part of the loop body where they belong.

The simple appearance of line 14 of this listing, compared to that of lines 12 and 13 in Listing 9.5, allows the reader to easily grasp the essential workings of this for loop.

i and j As Names for Counting Variables

graphics/common.gif

The use of i and j as names for counting variables has a long (in terms of computing history) history behind it. The tradition was established with the FORTRAN language in that it only allowed variables with the names i, j, k, l, m, and n to be used for counting purposes. The impact of this tradition is widespread throughout the programming community where you will often encounter those names used for counting variables.



   


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net