C# offers more looping statements than the while statement. In this section, you'll learn about the other looping possibilities.
Before we move on to new looping statements, let's briefly revisit our old friend the while loop now that you know about boolean expressions. In addition to their usefulness in if statements, boolean expressions also appear in while loops. The loop comparison doesn't have to be a simple relational comparison; it can be any boolean expression. For example:
Console.Write("Enter a number between 1 and 10:"); int num = Convert.ToInt32(Console.ReadLine()); while (!(num >= 1 && num <= 10)) { Console.Write("Enter a number between 1 and 10:"); num = Convert.ToInt32(Console.ReadLine()); }
This code fragment asks the user to enter a number between 1 and 10. The boolean logic ensures that the user enters a number in the required range.
Tip | |
---|---|
If you're writing a complicated expression in a loop condition, and you're not sure whether to use an && or an ||, it's usually safest to stick with &&. If you use ||, you increase the likelihood of an infinite loop, because both operands of the || must be false in order to get out of the loop. |
Sometimes it is more convenient to test the loop condition at the end of a loop, instead of at the beginning, as is done in the while loop. The do..while statement is very similar to the while statement, except that the word "while," along with the condition that it tests, has been moved to the end. The word "do" is added to mark the beginning of the loop. A do..while statement has the form
do statement while ( boolean-expression );
or, since, as usual, the statement can be a block,
do { statements } while ( boolean-expression );
Note the semicolon, ';', at the end. This semicolon is part of the statement, just as the semicolon at the end of an assignment statement or declaration is part of the statement. Omitting it is a syntax error. (More generally, every statement in C# ends either with a semicolon or a right brace, '}'.)
To execute a do loop, the computer first executes the body of the loop -- that is, the statement or statements inside the loop -- and then it evaluates the boolean expression. If the value of the expression is true, the computer returns to the beginning of the do loop and repeats the process; if the value is false, it ends the loop and continues with the next part of the program. Since the condition is not tested until the end of the loop, the body of a do loop is executed at least once.
For example, consider the following pseudocode for a game-playing program. The do loop makes sense here instead of a while loop because with the do loop, you know there will be at least one game. Also, the test that is used at the end of the loop wouldn't even make sense at the beginning:
do { Play a Game Ask user if he wants to play another game Read the user's response } while ( the user's response is yes );
Let's convert this into proper C# code. Since I don't want to talk about game playing at the moment, let's say that we have a class named Checkers, and that the Checkers class contains a static member subroutine named playGame() that plays one game of checkers against the user. Then, the pseudocode "Play a game" can be expressed as the subroutine call statement "Checkers.playGame();". We need a variable to store the user's response. So, the algorithm can be coded as
bool wantsToContinue; // True if user wants to play again. do { Checkers.playGame(); Console.Write("Do you want to play again? (y/n)"); string answer = Console.ReadLine(); wantsToContinue = (answer == "y"); } while (wantsToContinue);
When the value of the wantsToContinue is set to false, it is a signal that the loop should end. When a boolean variable is used in this way -- as a signal that is set in one part of the program and tested in another part -- it is sometimes called a flag or flag variable (in the sense of a signal flag).
Although a do..while statement is sometimes more convenient than a while statement, having two kinds of loops does not make the language more powerful. Any problem that can be solved using do..while loops can also be solved using only while statements, and vice versa. In fact, if doSomething represents any block of program code, then
do { doSomething } while ( boolean-expression );
has exactly the same effect as
doSomething while ( boolean-expression ) { doSomething }
Similarly,
while ( boolean-expression ) { doSomething }
can be replaced by
if ( boolean-expression ) { do { doSomething } while ( boolean-expression ); }
without changing the meaning of the program in any way.