Skip to content
Lesson 5 of 12

Step 1 of 6 · Reading · ~4 min

Learn

Control Flow

Loops

By the end of this lesson you can repeat work with for, while, do-while and foreach, choose the right one, and keep a loop from running one time too many or never stopping.

C# has four loop forms. The choice mostly comes down to one question: do you know how many times you are going around, or are you waiting for something to become true?

for: when you can count the iterations

int total = 0;
for (int i = 1; i <= 4; i++) {
    total += i * 10;
}
Console.WriteLine(total);   // 100

The header packs three parts: the initializer (int i = 1, runs once), the condition (i <= 4, checked before every pass, so the body can run zero times) and the update (i++, runs after each pass). Tracing the values is the best way to understand a loop:

passitotal after the body
1110
2230
3360
44100

After pass 4, i becomes 5, the condition 5 <= 4 is false and the loop ends. Off-by-one errors live entirely in the condition: i < 4 would run three times, i <= 4 runs four. When a bug is "one too many" or "one too few", read the condition first.

while and do-while: when you are waiting for a condition

int v = 4096;
int digits = 0;
while (v > 0) {
    v = v / 10;        // drop the last digit
    digits++;
}
Console.WriteLine(digits);   // 4

while checks the condition first, so the body may run zero times (with v = 0 this prints 0). do { ... } while (cond); checks after, so the body always runs at least once: the natural fit for "ask, then ask again until the answer is valid".

The number of passes is not known in advance here: it depends on the data. The body must change something the condition looks at. If it does not, the loop never ends, and the grader stops your program with a time limit.

foreach: when you have a sequence to walk through

string word = "cab";
foreach (char c in word) {
    Console.WriteLine(c);
}

This prints c, a and b on separate lines: a string is a sequence of characters, and foreach visits them in order. The collections lesson later shows lists and arrays, which foreach walks the same way. There is no index to get wrong, so use it whenever you do not need the position. Inside any loop, break leaves the innermost loop immediately and continue skips to the next pass.

Big values need big types

A loop that grows a number can pass int's ceiling of about 2.1 billion without any warning, and the value wraps negative. If the values can get large, use long (ceiling about 9.2 quintillion):

long size = 1;
int steps = 0;
while (size < 5000000000L) {
    size *= 3;
    steps++;
}
Console.WriteLine(steps + " steps, size " + size);   // 21 steps, size 10460353203

With int size the same loop would wrap around to a negative number and quite possibly never finish.

Common mistakes

  • Off by one in the condition. < versus <= changes the number of passes by one. Trace the first and the last pass.
  • A body that never changes the condition's variable. while (v > 0) with no update runs forever.
  • Counting from the wrong start. Starting i at 0 when the loop should see 1 changes every result that uses i.
  • An accumulator that overflows. int wraps at 2,147,483,647; the output is a wrong number, not an error.

Your exercise

The starter reads a number and sets up the variables you need. Repeat the rule described in the exercise until the number reaches 1, counting passes. The number of passes is not known in advance, and the numbers in the middle of the sequence can get much larger than the starting number; the most likely mistake is a variable type that is too small.

Up nextDefining MethodsMethods

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…