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:
| pass | i | total after the body |
|---|---|---|
| 1 | 1 | 10 |
| 2 | 2 | 30 |
| 3 | 3 | 60 |
| 4 | 4 | 100 |
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
iat 0 when the loop should see 1 changes every result that usesi. - An accumulator that overflows.
intwraps 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.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…