cadence_learn
the_c++_track / level 08 of 15 ▶ 15 min

four parts, going round.

Step a for loop one part at a time, then take the i++ away and watch the check never change its mind. The third shape is still where the bugs live.

after this level you'll be able to
  • Say which of the four parts of a for loop runs when
  • Choose between for and while without thinking about it
  • Find an off-by-one by checking only the first and last lap
level 3, in c++

the third shape, with punctuation

Repetition was the shape where bugs live, and that has not changed. C++ gives you three ways to write it, and they are the same idea underneath.

// when you know how many times for (int i = 0; i < 5; i++) { cout << i; } // when you do not — you are waiting for something to change while (guess != answer) { cin >> guess; } // when it must happen at least once before you can ask do { cin >> guess; } while (guess != answer);

Use for when you are counting, while when you are waiting. That single sentence covers almost every loop you will write this year.

the four parts of a for loop
for (int i = 0; i < 5; i++) { cout << i; } 1 · SETUP runs ONCE 2 · CHECK still true? 3 · BODY do the work 4 · STEP i++ 5 · DONE check is false back to the check — never back to the setup Take the step away and the check never changes its mind. That is an infinite loop, and it is the same shape as the missing “add 1 to count” from level 3.
Four parts, and only the setup is a one-off. Check → body → step → check, round and round, until the check finally says no.
◈ ask an ai about this

“What is the difference between for, while and do-while in C++, and how do I choose?”

chatgpt ↗ claude ↗

try it yourself

step the four parts

Watch which part fires next. The setup goes once and never again — everything after that is check, body, step, forever.

▤ lab 07a · the loop, one part at a time

Press step. Then take the i++ away and press it again.

 
Press step and watch the order. Setup, check, body, step, check, body, step…
how to stop a runaway program

You will write an infinite loop this semester. When Terminal fills with output and will not stop, press Control + C. Not Command — Control. That interrupts the running program and gives you your prompt back. It is not a crash and you have broken nothing.

the off-by-one

one character, one extra lap

The most common loop bug in existence is not exotic. It is < where you meant <=, or the other way round.

▤ lab 07b · count them

Same loop, one character apart. Verified against real output.

for (int i = 0; i < 5; i++)
0 1 2 3 4
five laps. Starts at 0, stops before 5.
for (int i = 0; i <= 5; i++)
0 1 2 3 4 5
six laps. Almost never what you wanted.

Counting from 0 and stopping before the total is the C++ habit, and it is not arbitrary — it is exactly how lists are numbered, which you meet in the next level. Learn the shape i = 0; i < n; i++ as one unit and you will use it thousands of times.

how to check a loop without running it

Trace it — level 4, and it works exactly the same on real code. Write a column for i, one row per lap, and check the first and last rows. Loops are almost always right in the middle and wrong at the ends, so those are the only two rows worth your time.

◈ ask an ai about this

“Why do C++ loops usually start at 0 and use < rather than <=? What is an off-by-one error?”

chatgpt ↗ claude ↗

leaving early, and skipping one

break and continue

Two words let you interrupt a loop mid-lap. They look similar and they do very different things — verified output below.

for (int i = 0; i < 8; i++) { if (i == 3) break; cout << i; } // 0 1 2 — break LEAVES the loop entirely for (int i = 0; i < 8; i++) { if (i == 3) continue; cout << i; } // 0 1 2 4 5 6 7 — continue SKIPS this lap and carries on

break means stop. continue means skip this one. Use break when you have found what you were looking for and there is no point going on — searching a list is the obvious case. Use continue to ignore items that do not qualify without nesting everything inside an if.

the one that hangs

continue in a while loop skips everything below it — including the line that changes your counter. That is an infinite loop with a very innocent-looking cause, and it is why continue is safer in a for, where the step is part of the loop itself and always runs.

Both also apply only to the innermost loop they are inside. In a loop within a loop, break leaves the inner one and the outer one carries straight on — which surprises people every single time.

the third loop

do-while, for when it must happen once

A while loop checks first and might never run at all. A do-while runs the body first and checks afterwards, so it always happens at least once. Verified with a value that fails the test from the start:

int n = 99; do { cout << "[ran]"; } while (n < 5); // prints [ran] — once while (n < 5) { cout << "[ran]"; } // prints nothing at all

Note the semicolon after the closing while — it is required there and nowhere else, and forgetting it produces a confusing error.

when you actually want it

Asking someone for input. You cannot check whether their answer is valid until you have asked for it once, so ask, then check, then ask again if needed is the natural shape:

do { cout << "Age: "; cin >> age; } while (age < 0);

That is nearly the only time it beats a plain while — which is why you will see it far less often than the other two.

one more thing

where the counter lives

A variable declared in the setup exists only inside the loop. After the closing brace it is gone, and asking for it will not compile:

for (int i = 0; i < 5; i++) { } cout << i; // error: use of undeclared identifier 'i'

That is deliberate and it is a kindness. If you genuinely need the value afterwards — how many did we get through before it stopped? — declare it before the loop instead. This is called scope, and it is the same idea that makes functions safe in the next level.

do this together

count out loud, badly

☶ two people · 12 minutes

One is the loop. One checks the count on their fingers.

person a — the loop

Say a loop out loud: “start at 1, keep going while it is under 5, add 1 each time.” Then perform it, saying every number.

person b — the counter

Predict how many numbers will be said before A starts. Not which numbers — how many. Then count on your fingers.

Try the four combinations: start at 0 or 1, stop with < or <=. Only one of the four gives exactly five laps starting from zero, and getting that wrong by one is what an off-by-one error is. Then have A deliberately forget the “add 1” and let it run for ten seconds — feeling it is worth more than reading about it.

what to keep

three things worth remembering

01

for counts, while waits

Known number of laps takes a for. Waiting for something to change takes a while.

02

Check the first and last lap

The middle is always fine. Every off-by-one lives at one of the two ends.

03

Control + C

Stops a runaway program. You will need it, and it breaks nothing.

check yourself

5 questions before you move on

Not recall — these are the shapes an exam actually uses. Every answer below was produced by compiling and running the code, so if you disagree with one, the compiler is the one to believe.

▢ check yourself5 questions

Have a real go before revealing. Being wrong here is worth more than being right in three weeks.

01

What does this print?

for (int i = 0; i < 5; i++) cout << i;
02

How many times does this loop run?

for (int i = 0; i <= 5; i++) { ... }
03

What does this print?

for (int i = 0; i < 8; i++) { if (i == 3) continue; cout << i; }
04

n is 99, which is not less than 5. What does this print?

int n = 99; do { cout << "ran"; } while (n < 5);
05

You write continue inside a while loop, above the line that increases the counter. What happens?

answered: 0 of 5right first time: 0
Stuck? Peter reads these personally and replies to your email.
Ask Peter →