8 min read

Loops

The Crash Course

Introduction

In C#, statements are generally executed one after the next, from top to bottom. We saw if statements and switches that allow us to select which statements to run, based on conditions. Now we’ll look at how to repeat code more than once. Repeating code multiple times is done with a construct called a loop .

C# has four different types of loops. We’ll discuss three of the four here, and cover the next one in the next tutorial.

The while Loop

The most fundamental loop is called a while loop. This is another one of those times where it is easier to just show an example than to describe it, so look at this code, which will print out the numbers 1 through 5:

int x = 1;

while (x <= 5)
{
    Console.WriteLine(x);
    x++;
}

Console.WriteLine("All done.");

A while loop looks somewhat similar to an if statement. It begins with the while keyword, and then contains a loop condition in parentheses. Everything “inside” the loop (in this case, the block that encompasses the curly braces) will run over and over, for as long as the condition is true.

Let’s walk through it.

The variable x is initialized to 1.

Then the while loop’s condition is checked because we arrive at the top of the loop. Since x is 1, which is less than or equal to 5, we execute the loop’s body, and run through the statements in the block.

note

Like an if statement, a loop can be wrapped around a single statement or a block statement. The code above uses a block statement.

We reach the Console.WriteLine and display the current value of x, which is 1. We then increment x (the x++; statement). At this point, x now contains the value 2.

note

Loops are a primary example of where the increment and decrement operators are used.

After incrementing x, we reach the end of the loop.

Instead of continuing on past the loop, we return to the top of the loop, and re-evaluate its condition.

Since 2 is still less than or equal to 5, we run the loop a second time. This time through, we write out the 2, and increment again, leaving a value of 3 in the variable x.

We go back to the top of the loop yet again. We’ll do this a few more times as we work our way through x being 3, then 4, and then 5.

In the pass through the loop where we display the 5, we finally increment x to 6, and things get interesting for us.

We go back to the start of the loop, but this time, our loop’s condition is not true anymore! 6 is not less than or equal to 5.

At this point we do not run the loop again.

The flow of execution jumps down past the loop and runs the final statement, which displays "All done." in the console window.

By picking different loop conditions, we can come up with all sorts of clever ways to repeat code more than once. For example, consider this question: how could you modify the above code to ask the user for a number and then count up to the number the user entered?

warning

Every time through a loop, you should be doing something that will change the loop’s condition somehow. If the code above left out the x++; line, this loop would continue forever and your program would never end. Such a loop is called an infinite loop .

The do/while Loop

The second type of loop in C# is a slight variation on the while loop: the do/while loop.

One key point about while loops is that they check their condition at the beginning. Sometimes, you’d prefer to check the condition at the end instead.

info

There isn’t much difference between while and do/while loops. However, the fact that do/while loops are checked at the end means the loop will always run at least once. That isn’t true of while loops. This is usually the clue that tells you which of the two loops you want.

Here’s an example of a do/while loop that gets a number from a user, but keeps asking until they enter something in the range of 1 through 10:

int number;

do
{
    Console.Write("Enter a number between 1 and 10 (inclusive): ");
    number = Convert.ToInt32(Console.ReadLine()); // Combining two things together here. The output from
                                                  // `ReadLine` is immediately fed into the `ToInt32` method.
}
while (number < 1 || number > 10); // Don't forget this semicolon.

The do/while loop starts with the do keyword. We prompt the user to enter a number, and tell them the conditions. We then get the number and convert it to an int (ToInt32).

The condition in the while at the bottom checks to ensure the value entered was in the right range. If the user entered 99, then the program will have them ask again. If they entered 5, the condition will be false and we’ll leave the loop instead of running it again.

The for Loop

Let’s analyze the following loop again:

int x = 1;

while (x <= 5)
{
    Console.WriteLine(x);
    x++;
}

Console.WriteLine("All done.");

The biggest problem with this loop is that so much of what’s going on is about managing the looping mechanism. The first line sets up a variable that is used in the loop. Then the while loop is there, with its condition. And the last line in the while loop is there to move on to the next cycle in the loop.

There is really only one meaty line in that, aside from the loop.

A for loop compresses all of these parts–the variable initialization, the condition, and the increment to move between loops–into a single, compact representation. The following is the for loop equivalent to the previous sample:

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

Console.WriteLine("All done.");

In fact, now that there’s only one line left in that particular for loop, we can ditch the block and just use a single statement:

for (int x = 1; x <= 5; x++)
    Console.WriteLine(x);

Console.WriteLine("All done.");

What was 9 lines of code is now 4. Just as importantly, all of the loop control code is brought together in one place.

With a while loop, it is actually quite easy to forget the whole x++; part. Since a for loop has a spot reserved for that type of thing, it is much harder to forget.

Having said that, you could write any loop with any of the above three loop types. So pick the one that makes the code the most understandable.

break and continue

The break and continue keywords give you a little extra control over looping.

The break keyword lets you escape a loop, regardless of the condition, in case you detect that it is time to be done with the loop.

A simple example of break is the following, which parrots back anything the user types until they type "bye":

while (true)
{
    string message = Console.ReadLine();
    Console.WriteLine(message);

    if (message == "bye") break;
}

Here, we have a loop that would otherwise loop forever (while (true) will do that). But when the message is right, the flow of execution will reach that break; statement, and we’ll jump out of the loop and end the program.

The continue keyword lets you jump forward to the next iteration in the loop.

note

For a for loop, this will also run whatever code you used for moving on to the next loop.

This is useful if you can detect, part way through executing a loop, that there’s no need to continue:

while (true)
{
    string message = Console.ReadLine();

    if (message == "nothing") continue;

    Console.WriteLine(message);
}

In this version of the code, if you type "nothing", then the rest of the loop is skipped. It won’t hit the Console.WriteLine statement, and move back to the start of the loop.

Nested Loops

Like with an if statement, you can nest loops. You can put a for loop in a for loop, a while in a do/while, and a for in a for in a while. Any combination that makes sense for what you’re trying to accomplish.

Additionally, you can put if statements in loops, and loops in if statements.

There are not limitations to speak of in this regard, other than keep it as simple as you can. When things are deeply nested, it starts to get really hard to understand what is going on when you’re reading the code later on.

As an illustration, the following code will display a 2D grid of * characters:

for (int row = 0; row < 5; row++)
{
    for (int column = 0; column < 10; column++)
        Console.Write("*");
    Console.WriteLine(); // Moves down a line without writing any other text.
}

challenge

Before you move on, try out this challenge to prove your skills.