Looping in C#

Looping

The Crash Course

  • while loops, do/while loops, and for loops all exist in C#, and work exactly like they do in C++ and Java.
while (condition) { /* ... */ }
 
do { /*... */ } while(condition);
 
for (initialization; condition; update) { /* ... */ }
  • You can break out of a loop at any time with the break keyword and advance to the next iteration of the loop with the continue keyword.
  • The foreach loop is discussed in the next tutorial.

Introduction

Having just covered the powerful if statement, we're going to move on to yet another very powerful construct in the C# language: loops. Loops allow you to repeat sections of code repeatedly. We'll discuss three types of loops here in this tutorial, and we'll cover the fourth type in the next tutorial when we discuss arrays (it makes a lot more sense with arrays).

The while Loop

The first kind of loop we're going to talk about is the while loop. A while loop will repeat code over and over while a certain condition is true. This will make a lot more sense in a second when we see our first example. While loops are constructed in a way that looks a whole lot like an {if} statement:

while ( condition )
{
    // This code is repeated until the condition is false.
}

Let's start with a really simple example that counts to ten:

int x = 1;
while (x <= 10)
{
    Console.WriteLine(x);
    x++;
}

This starts with x being 1. The program then checks the condition in the while loop"is x less than or equal to 10?"which is true, so the stuff inside the while loop gets executed. It writes out the value of x, 1, then increments x (remember that means it adds one to it). Then it reaches the end of the while loop when it hits that last curly brace and jumps back up to the beginning of the loop, checking the condition again. This time, however, x has changed. It is now 2. The condition is still true, though (2 is still less than or equal to 10), and the loop repeats again, printing out "2" and incrementing x to 3. This will happen 10 times total when finally, x will get incremented to 11, and when the program checks to see if 11 is less than or equal to 10, it is no longer true, and the flow of execution will jump down past the end of the loop.

One thing to keep in mind is that it is easy to end up with a bug in your code that inadvertently makes it so a loop's condition is never false met. Imagine (or don't imagine—try it out) that the x++; line wasn't there. The program would keep repeating the loop, and each time, x would still be 1. The program would never end! This problem is actually common enough to be given its own name: an infinite loop. I promise you, by the time you're done making your first "real" program or game, you will be the proud writer of at least one infinite loop. It happens. (And you need to kill your program, fix the bug, and restart.)

While we're on the subject of infinite loops, I'm going to mention that sometimes, people make them on purpose. It sounds strange, I know. But it is easy to do:

while (true)
{
    // Depending on what goes in here, you'll never end...
}

Some people refer to intentional infinite loops by the name forever loop, though even just calling it an intentional infinite loop is, perhaps, more common.

You can still escape such a loop, depending on what is inside of the loop (such as a break;, which we'll discuss in a moment).

Moving on, here's a more complicated example that repeats over and over until the user enters a number between 0 and 10:

int playersNumber = -1;
 
while (playersNumber < 0 || playersNumber > 10)
{
    // This code will get repeated until the player finally types in a number between 0 and 10.
 
    Console.Write("Enter a number between 0 and 10:  ");
    string playerResponse = Console.ReadLine();
    playersNumber = Convert.ToInt32(playerResponse);
}

One important thing to remember with a while loop is that it always checks the condition before even going into the loop. So if the condition is not met, it doesn't ever go in the loop right from the get-go. In this little example above, it is important that we initialize playersNumber to -1 because if we had started it at, say, 0, the flow of execution would have jumped right over the inside of the while loop, and the player would have never been able to choose a number.

The do/while Loop

The next type of loop we'll look at is a slight variation on the while loop. It is the do/while loop. Remember what I just said: before even starting the loop, a while loop will check the condition to see if it is met, and if not, it could skip the loop entirely. (Might I add that this isn't bad; it is just something to remember. Much of the time, that's exactly how you want it.)

Well, a do/while loop will always get executed at least once. This can be useful if you are trying to set up some stuff the first time through the loop, and you know it needs to be executed at least once.

Let's revisit that last example because it was a prime candidate for a do/while loop. Remember, we needed to set up the player's number to -1, to force it to go through the loop at least once? Doing this as a do/while loop solves the need for that:

int playersNumber;
 
do
{
    Console.Write("Enter a number between 0 and 10:  ");
    string playerResponse = Console.ReadLine();
    playersNumber = Convert.ToInt32(playerResponse);
}
while (playersNumber < 0 || playersNumber > 10);

To form a do-while loop, we put the do keyword at the start of the loop, and at the end, we put the while keyword. Notice, too, that you need a semicolon at the end of the while line. Everything else is the same, but you don't need to initialize the playersNumber variable this time.

The for Loop

Now let's take a look at a slightly different kind of loop: the for loop. for loops are very common in programming. They are an easy way of doing "counting" type loops, and we'll see how useful they are again in the next tutorial with arrays. for loops are a bit more complicated to set up because they require three components inside of the parentheses, whereas while and do/while loops have only required one. It is structured like this:

for (initial condition; condition to check; action at end of loop)
{
    //...
}

There are three parts, separated by semicolons. The first part sets up the initial state, the second part is the condition (the same thing that was in the while and do-while loops), and the third part is an action that is performed at the end of the loop. An example would probably go a long way here, so let's do the counting to ten example again, this time as a for loop:

for(int x = 1; x <= 10; x++)
{
    Console.WriteLine(x);
}

Note that we can declare and initialize a variable right inside of the for loop, as we do here, with int x = 1;.

One of the reasons why this kind of loop is so nice is because it separates the looping logic from what you're actually doing with the number. Rather than having the x++ command inside of the loop, and declaring the variable before the loop, all of that stuff is just packed into the loop control mechanism, making it so the body of the loop is much clearer.

Another cool thing to point out is that basically, you can do anything with one type of loop with the other two. Sometimes one method looks cleaner or is easier to understand, but they are all looping mechanisms, and the same thing can be done with any one of them. If suddenly the C# world ran out of while keywords, and all you had left was fors, you'd be fine.

Breaking Out of Loops

Another cool thing you can do with a loop is "break" out of it any time you want. Sometimes, as you're doing stuff, you get to a point inside of a loop (any of the types) where you know there's no point in continuing with the loop. You can jump out of a loop whenever you want with the break keyword, like this:

int numberThatCausesProblems = 54;
 
for (int x = 1; x <= 100; x++)
{
    Console.WriteLine(x);
 
    if (x == numberThatCausesProblems)
    {
        break;
    }
}

This code will only go until it hits 54, at which point, the if statement catches it and sends it out of the loop. This is kind of a trivial example, but it is a good idea of when you might use the break command. When we start the loop, we're fully expecting to get to 100, but then we realize at some point, that there's a critical problem, and that we need to just jump out of the loop.

This, by the way, is the kind of thing that lets us escape an intentional infinite loop:

while (true)
{
    Console.Write("What is thy bidding, my master?  ");
    string input = Console.ReadLine();

    if (input == "quit" || input == "exit")
    {
        break;
    }
}

Continuing to the Next Iteration of the Loop

In a similar matter to what we saw with the break command, there's another command that, rather than getting out of the loop altogether, just jumps back to the start of the loop and checks the condition again. In other words, it continues on to the next iteration of the loop without finishing the current one.

This is done with the continue keyword:

for (int x = 1; x <= 10; x++)
{
    if (x == 3)
    {
        continue;
    }
 
    Console.WriteLine(x);
}

In this code sample, all of the numbers will get printed out, with one exception: 3 gets skipped because of the continue statement. When it hits that point, it jumps back up, runs the x++ part of the loop, checks the x < 10 condition again, and continues on with the next cycle through the loop.

Nesting Loops and Some Practice

Like with if statements, it is possible to nest loops. And to put if statements inside of loops and loops inside of if statements. You can go absolutely crazy with all of this control!

Let me show you an example or two, and then I'm going to give you the "assignment" to come up with the code for another similar thing.

I'm going to repeat a really simple example that I still, to this day, remember from when I first started learning to program. (Back then, it was C++, not C#, and we had to walk uphill, both ways to school!) The task was to write a loop that would print out the following using loops (you were only allowed to have the * character in your program once):

**********
**********
**********
**********
**********

The code to do this is this:

for (int row = 0; row < 5; row++)
{
    for (int column = 0; column < 10; column++)
    {
        Console.Write("*");
    }
 
    Console.WriteLine(); // This makes it wrap back around to the beginning again.
}

Let's try one more, slightly harder one before I give you your "assignment":

If we want to do this:

*
**
***
****
*****
******
*******
********
*********
**********

the code would be:

for (int row = 0; row < 10; row++)
{
    for (int column = 0; column < row + 1; column++)
    {
        Console.Write("*");
    }
 
    Console.WriteLine();
}

Notice how tricky we were, using the row variable in the condition of the for loop with the column variable.

Oh, and I should probably mention (because I'm sure you're wondering) that programmers seem to love 0-based indexing, meaning we love to start at 0. (I guess we, programmers, are supposed to start counting "0, 1, 2, 3, …" instead of "1, 2, 3, …". But I don't.) So you'll see what I've done here very frequently. I start with row and column at 0 and go up to the amount I want (10 in this case), but not including it. That does it 10 times. You could do it starting at 1 and doing row <= 10 instead, but what I wrote is more typical for the most programmers.

Now, for your assignment. Try coming up with the code to get this:

     *     
    ***    
   *****   
  *******
 *********
***********

Trust me, it is not simple. But you really should try it out. Here's the reason why. You've gotten to the point where you can actually start doing stuff. But if you're just reading the tutorial and doing nothing, it will be difficult to pick up the stuff you need out of these tutorials. So give it a shot.

You may also find it helpful to try to recreate the simpler star patterns without copying and pasting my code first since they are easier.

If you try for 10 minutes, and you're still stuck, don't worry. Take a look at the hidden code below:

Still to Come: foreach

It is worth mentioning that we have one more type of loop to discuss, which we'll do in the next tutorial: the foreach loop. (Just so you people who already know C# don't get mad at me!)

What's Next?

We've discussed all sorts of ways to create loops and (hopefully) had a bit of practice thinking through them. Loops are extremely powerful tools, and you'll get to know the ins and outs much better as time goes on. It can sometimes take a little getting used to but don't worry if you're having a little trouble. It usually takes time.

Our next stop is arrays: cool features that let us store lots of stuff all together.