Jump Statements


It is possible to alter the execution path of a loop. In fact, with jump statements, it is possible to escape out of the loop or to skip the remaining portion of an iteration and begin with the next iteration, even when the conditional expression remains true. This section considers some of the ways to jump the execution path from one location to another.

The break Statement

To escape out of a loop or a switch statement, C# uses a break statement. Whenever the break statement is encountered, the execution path immediately jumps to the first statement following the loop. Listing 3.47 examines the foreach loop from the tic-tac-toe program.

Listing 3.47. Using break to Escape Once a Winner Is Found

class TicTacToe     // Declares the TicTacToe class. {     static void Main()      // Declares the entry point of the program.     {        int winner=0;        // Stores locations each player has moved.        int[] playerPositions = {0,0};        // Hardcoded board position        // X | 2 | O        // ---+---+---        // O | O | 6        // ---+---+---        // X | X | X        playerPositions[0] = 449;        playerPositions[1] = 28;        // Determine if there is a winner        int[] winningMasks = {                   7, 56, 448, 73, 146, 292, 84, 273 };        // Iterate through each winning mask to determine        // if there is a winner.        foreach(int mask in winningMasks)                                            {                                                                                  if ((mask & playerPositions[0]) == mask)              {                    winner = 1;                    break;                                                                 }              else if ((mask & playerPositions[1]) == mask)              {                    winner = 2;                    break;                                                                 }  }                                                                            System.Console.WriteLine(       "Player {0} was the winner", winner); } }

Output 3.24 shows the results of Listing 3.47.

Output 3.24.

Player 1 was the winner

Listing 3.47 uses a break statement when a player holds a winning position. The break statement forces its enclosing loop (or a switch statement) to cease execution, and the program moves to the next line outside of the loop. For this listing, if the bit comparison returns true (if the board holds a winning position), the break statement causes execution to jump and display the winner.

Beginner Topic: Bitwise Operators for Positions

The tic-tac-toe example (Appendix B) uses the bitwise operators to determine which player wins the game. First, the code saves the positions of each player into a bitmap called playerPositions. (It uses an array so that the positions for both players can be saved.)

To begin, both playerPositions are 0. As each player moves, the bit corresponding to the move is set. If, for example, the player selects cell 3, shifter is set to 3 1. The code subtracts 1 because C# is zero based and you need to adjust for 0 as the first position instead of 1. Next, the code sets position, the bit corresponding to cell 3, using the shift operator 000000000000001 << shifter, where shifter now has a value of 2. Lastly, it sets playerPositions for the current player (subtracting 1 again to shift to zero based) to 0000000000000100. Listing 3.48 uses |= so that previous moves are combined with the current move.

Listing 3.48. Setting the Bit That Corresponds to Each Player's Move

[View full width]

int shifter;  // The number of places to shift                                                  // over in order  to set a bit. int position; // The bit which is to be set // int.Parse() converts "input" to an integer. // "int.Parse(input) 1" because arrays // are zero based. shifter = int.Parse(input)- 1; // Shift mask of 00000000000000000000000000000001 // over by cellLocations. position = 1 << shifter; // Take the current player cells and OR them to set the // new position as well. // Since currentPlayer is either 1 or 2, // subtract one to use currentPlayer as an // index in a 0-based array. playerPositions[currentPlayer-1] |= position;

Later on in the program, you can iterate over each mask corresponding to winning positions on the board to determine if the current player has a winning position, as shown in Listing 3.47.


The continue Statement

In some instances, you may have a series of statements within a loop. If you determine that some conditions warrant executing only a portion of these statements for some iterations, you use the continue statement to jump to the end of the current iteration and begin the next iteration. The C# continue statement allows you to exit the current iteration (regardless of which additional statements remain) and jump to the loop conditional. At that point, if the loop conditional remains true, the loop will continue execution.

Listing 3.49 uses the continue statement so that only the letters of the domain portion of an email are displayed. Output 3.25 shows the results of Listing 3.49.

Listing 3.49. Determining the Domain of an Email Address

class EmailDomain {  static void Main()  {   string email;   bool insideDomain = false;   System.Console.WriteLine("Enter an email address: ");   email = System.Console.ReadLine();   System.Console.Write("The email domain is: ");   // Iterate through each letter in the email address.   foreach (char letter in email)   {       if (!insideDomain)       {         if (letter == '@')         {            insideDomain = true;         }         continue;       }       System.Console.Write(letter);    }   } }

Output 3.25.

Enter an email address: mark@dotnetprogramming.com The email domain is: dotnetprogramming.com

In Listing 3.49, if you are not yet inside the domain portion of the email address, you need to use a continue statement to jump to the next character in the email address.

In general, you can use an if statement in place of a continue statement, and this is usually more readable. The problem with the continue statement is that it provides multiple exit points within the iteration, and this compromises readability. In Listing 3.50, the sample has been rewritten, replacing the continue statement with the if/else construct to demonstrate a more readable version that does not use the continue statement.

Listing 3.50. Replacing a continue with an if Statement

foreach (char letter in email) {    if (insideDomain)    {           System.Console.Write(letter);    }    else    {           if (letter == '@')           {               insideDomain = true;           }     } }

The goto Statement

With the advent of object-oriented programming and the prevalence of well-structured code, the existence of a goto statement within C# seems like an aberration to many experienced programmers. However, C# supports goto, and it is the only method for supporting fallthrough within a switch statement. In Listing 3.51, if the /out option is set, code execution jumps to the default case using the goto statement; similarly for /f.

Listing 3.51. Demonstrating a switch with goto Statements

 // ... static void Main(string[] args) {  bool isOutputSet = false;  bool isFiltered = false;  foreach (string option in args)  {      switch (option)      {          case "/out":              isOutputSet = true;              isFiltered = false;              goto default;                                                             case "/f":              isFiltered = true;              isRecursive = false;              goto default;                                                             default:              if (isRecursive)              {                    // Recurse down the hierarchy                    // ...              }              else if (isFiltered)              {                 // Add option to list of filters.                 // ...              }              break;       }   }   // ... }

Output 3.26 shows the results of Listing 3.51.

Output 3.26.

C:\SAMPLES>Generate /out fizbottle.bin /f "*.xml" "*.wsdl"

As demonstrated in Listing 3.51, goto statements are ugly. In this particular example, this is the only way to get the desired behavior of a switch statement. Although you can use goto statements outside switch statements, they generally cause poor program structure and you should deprecate them in favor of a more readable construct. Note also that you cannot use a goto statement to jump from outside a switch statement into a label within a switch statement.




Essential C# 2.0
Essential C# 2.0
ISBN: 0321150775
EAN: 2147483647
Year: 2007
Pages: 185

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