2.4 Loop Control and Nested Loops
SLO 2
Describe the principles of structured programming.
Structured programming allows a loop exactly two controlled escapes, and this is where you get them: break to leave, continue to skip one round. Nesting shows why break's reach is the inner loop only — each loop keeps its own single exit.
SLO 4
Explain what an algorithm is and its importance in computer programming.
An algorithm has to finish. Infinite loops are what happens when that guarantee is dropped, and naming the three usual causes turns termination into something you check rather than hope for. Tracing a nested loop tells you what the work actually costs.
Learning Objectives
After this section, you will be able to:
- Write a
whileloop and explain when to prefer it over aforloop. - Write a
do...whileloop and explain why its body always runs at least once. - Use
breakto leave a loop early andcontinueto skip a single round. - Recognize an infinite loop and name the three ways one is usually caused.
- Write a nested loop and trace how many times the inner body runs.
- Explain which loop
breakleaves when loops are nested.
2.4.1 Choosing a Loop: for vs while
Section 2.2 introduced both the for loop and the while loop and showed that they can express the same plan. This is the section where you learn to pick between them.
The two are genuinely interchangeable. Here is the same count, twice:
▶ Press Run to see the output…
What you should see:
for: 1 for: 2 for: 3 while: 1 while: 2 while: 3
The difference is not what they can do, it is what they say. A for loop gathers the start, the condition, and the update onto one line, where a reader can see all three at once. That is exactly what you want when you know the count in advance: "do this five times", "visit every item in the list".
A while loop puts nothing on that line except the condition. That is what you want when you do not know the count — when the loop runs until something becomes true, and how long that takes depends on the work itself.
▶ Press Run to see the output…
What you should see:
Doubled after 8 years.
Nobody writing that loop knew the answer was 8. That is the point — the condition, not a counter, decides when to stop.
A useful test: if you can say the number of repetitions out loud before running the program, reach for for. If the honest answer is "however many it takes", reach for while. Using for for the second case forces you to invent a counter you do not need, and using while for the first scatters the three parts of the loop across three different lines, which is where a forgotten update comes from.
1. Which loop fits better: printing every item in a list of 12 names?
for, because the number of repetitions is known.while, because lists can change.- Either — there is no difference at all.
Solution
a. for. The list has a length, so the count is known before the loop starts.
Option c is half right — the two loops can both do it — but "no difference at all" ignores readability, which is the whole reason both exist.
2. Which loop fits better: keep shuffling a deck until the top card is an ace?
for, because you can guess a maximum.while, because the number of shuffles is not known in advance.- Neither — this needs an
if.
Solution
b. while. The stopping point depends on the result of the work, not on a count.
2.4.2 The do...while Loop
Both loops you have met test their condition before running the body. If the condition is false at the start, the body never runs at all:
▶ Press Run to see the output…
What you should see:
Done. count is still 10
Sometimes that is wrong. If you are asking a user for input, checking a password, or rolling dice, the body has to run once before there is anything to test. The do...while loop puts the condition at the bottom:
▶ Press Run to see the output…
What you should see:
Attempt 1 Attempt 2 Attempt 3
A do...while loop runs its body first and tests its condition afterwards, repeating while the condition is true. Because the test comes last, the body always runs at least once, even when the condition is false from the start.
Definition 2.4.1 — A do...while loop runs its body first and tests its condition afterwards, repeating while the condition is true; because the test comes last, the body always runs at least once, even when the condition is false from the start.
Note the semicolon after the closing while (...). A do...while is the one loop that ends with one, and leaving it off is a common syntax slip.
Give both loops a condition that is false from the very beginning, and watch what each one does.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
do...while body ran
The while body ran zero times. The do...while body ran exactly once, then tested 100 < 10, found it false, and stopped. That "at least once" is the entire difference between the two.
do...while is the least-used of the three loops, and that is fine — most of the time you genuinely want the test first. Reach for it when the thing being tested does not exist until the body has run once: a value the user has not typed yet, a die that has not been rolled yet, a menu choice that has not been made yet.
Put this next to Figure 2.2.1 and the difference is one box moving.
Figure 2.4.1 — A do...while loop. The body sits above the diamond, so it always runs once before the condition is asked.
In Figure 2.2.1 the arrow from Start reaches the diamond first. Here it reaches the body first. There is no path from Start to End that skips the body -- which is exactly the "at least once" guarantee, drawn.
Put this next to Figure 2.2.1 and the difference is one box moving.
In Figure 2.2.1 the arrow from Start reaches the diamond first. Here it reaches the body first. There is no path from Start to End that skips the body -- which is exactly the "at least once" guarantee, drawn.
1. How many times does this body run?
▶ Press Run to see the output…
- Zero times
- Once
- Forever
Solution
b. Once.
The body runs before anything is tested. Then x is 1, 1 < 0 is false, and the loop ends.
Write a do...while loop that prints the numbers 1 through 5. Then change the condition so it is false immediately, and confirm that it still prints one line.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
1 2 3 4 5
Now change i <= 5 to i <= 0:
▶ Press Run to see the output…
Output:
1
The body still ran once, because the test happens after it.
2.4.3 Leaving Early with break
You met break in the linear search in Section 2.2: once the target was found, there was no reason to keep looking. break stops the loop immediately and continues with the code after it.
▶ Press Run to see the output…
What you should see:
1 2 3 Stopping at 4 After the loop.
The loop was written to count to 10 and got to 4. The condition i <= 10 never became false — break does not wait for it.
The break statement immediately ends the loop it is inside. Execution continues with the first statement after the loop, and the loop's own condition is never checked again.
Definition 2.4.2 — The break statement immediately ends the loop it is inside; execution continues with the first statement after the loop, and the loop's own condition is never checked again.
break also makes a certain kind of loop possible: one with no stopping condition of its own, where the only exit is the break.
Find the first number at or above 20 that divides evenly by 7. You do not know in advance how far you will have to look.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
Found: 21
while (true) is a condition that is never false. Written on its own, that is an infinite loop and a bug. Written with a break inside, it is a deliberate statement: this loop ends when it finds what it is looking for, and not before.
The % operator here gives the remainder of a division. 21 % 7 is 0, which is how you test whether one number divides evenly into another.
while (true) is only honest when the reader can see the exit. Keep the break near the top of the body where it is easy to find. If a while (true) loop grows long enough that its exit is buried, that is usually a sign the condition belongs in the while after all.
while (true) looks reckless written down. Charted, it is precise about exactly what it promises.
Figure 2.4.2 — while (true) with a break. The no exit of the top diamond is drawn but can never be taken, so the break is the only way out.
The no arrow off the top diamond greys out in your head the moment you read the condition: true is never false, so no execution ever travels it. Every path that reaches the End goes through the break. Delete the break box and the chart has no reachable End at all -- that is the picture of a hung program.
while (true) looks reckless written down. Charted, it is precise about exactly what it promises.
The no arrow off the top diamond greys out in your head the moment you read the condition: true is never false, so no execution ever travels it. Every path that reaches the End goes through the break. Delete the break box and the chart has no reachable End at all -- that is the picture of a hung program.
Write a loop that counts up from 1 and stops as soon as it reaches a number whose square is greater than 50. Print that number.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
8 squared is 64
7 * 7 is 49, which is not greater than 50, so the loop goes one more round.
2.4.4 Skipping a Round with continue
break leaves the loop. continue is gentler: it abandons only the current round and jumps straight to the next one.
▶ Press Run to see the output…
What you should see:
1 3 5
When i is even, continue skips the console.log and goes back to the top of the loop for the next value. The loop still runs all six rounds — it just does nothing useful in three of them.
The continue statement ends the current iteration of a loop and jumps to the next one. Unlike break, the loop itself keeps running.
Definition 2.4.3 — The continue statement ends the current iteration of a loop and jumps to the next one; unlike break, the loop itself keeps running.
Add up only the positive numbers in a list, ignoring the rest.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
Total of positive readings: 14
4 + 7 + 3 is 14. The zero and the two negatives were skipped.
That same loop can be written the other way round, with an if that keeps rather than a continue that skips:
▶ Press Run to see the output…
What you should see:
Total of positive readings: 14
Both are correct. continue earns its place when the thing you want to skip is checked at the top and the real work below it is long — it saves the reader from following a block of code wrapped in an if that runs to the bottom of the loop.
continue in a while loop is where this gets dangerous. In a for loop the update i++ lives in the loop header, so continue still runs it. In a while loop the update is a line in the body — and continue jumps straight past it. The counter never changes, the condition never becomes false, and the program hangs. If you use continue inside a while, check that the update happens before it.
continue does not leave the loop, and the chart is the quickest way to prove it to yourself.
Figure 2.4.3 — continue in a for loop. The skip arrow jumps past the work, but still lands on the update box before going round again.
Both paths -- the skipped one and the working one -- pass through the i = i + 1 box. That is the whole reason continue is safe in a for loop and dangerous in a while loop. In a while, the update is a line in the body, so it sits on the working path only: the skip arrow bypasses it, i never changes, and the condition never turns false.
continue does not leave the loop, and the chart is the quickest way to prove it to yourself.
Both paths -- the skipped one and the working one -- pass through the i = i + 1 box. That is the whole reason continue is safe in a for loop and dangerous in a while loop. In a while, the update is a line in the body, so it sits on the working path only: the skip arrow bypasses it, i never changes, and the condition never turns false.
continue trap, and its fixThe loop below is meant to print the odd numbers from 1 to 5. As written it would hang forever, so the fixed version is what runs here.
// BROKEN — do not run this. It never stops.
let i = 0;
while (i < 5) {
if (i % 2 === 0) {
continue; // jumps back up without ever reaching i++
}
console.log(i);
i++;
}
When i is 0, the condition is true, continue fires, and i is still 0. Nothing has changed, so the next round does exactly the same thing, forever. Moving the update above the continue fixes it:
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
1 3 5
1. What does this print?
▶ Press Run to see the output…
1 21 2 4 51 2 3 4 5
Solution
b. 1, 2, 4, 5 on separate lines.
continue skips only the round where i is 3. Had it been break, the output would have stopped at 1 2.
2. You are looking through a list for the first item that is out of stock, and you want to stop as soon as you find one. Which statement do you want?
breakcontinuedefault
Solution
a. break. "Stop as soon as you find one" is exactly what break does; continue would keep searching through the rest of the list for no reason.
Write a for loop over the numbers 1 to 20 that prints only the multiples of 3, using continue to skip the others.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
3 6 9 12 15 18
2.4.5 Infinite Loops
An infinite loop is a loop whose condition never becomes false. The program does not crash and does not print an error — it simply never finishes. In a browser tab, the page stops responding.
An infinite loop is a loop whose stopping condition is never satisfied, so it repeats forever. The program keeps running but never reaches the code after the loop.
Definition 2.4.4 — An infinite loop is a loop whose stopping condition is never satisfied, so it repeats forever; the program keeps running but never reaches the code after the loop.
Almost every infinite loop a beginner writes comes from one of three causes:
- The update is missing. The counter never changes, so the condition stays true.
// BROKEN: i is always 1
let i = 1;
while (i <= 5) {
console.log(i);
}
- The update moves the wrong way. The counter changes, but away from the condition.
// BROKEN: i only gets further from 5
for (let i = 1; i <= 5; i--) {
console.log(i);
}
- A
continueskips the update. Thewhiletrap from Section 2.4.4.
Each of these is a live loop with no output you can read, so the only fix is to inspect the three parts — start, condition, update — and ask whether the update actually moves the counter toward making the condition false.
Not every infinite loop is a bug. while (true) with a break is one on purpose, and every game and every operating system has a loop at its heart that is meant never to end — you will write one in Section 2.5. The bug is not "this loop runs forever", it is "this loop runs forever and I did not mean it to".
If you are ever unsure whether a loop terminates, add a counter that forces it to stop. This is a debugging tool, not something to leave in finished code.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
Finished with value 128 after 7 rounds.
The guard never tripped, which tells you the loop was fine. Change value = value 2 to value = value 1 and the guard is the only reason your browser survives.
1. Why does this loop never end?
let count = 10;
while (count > 0) {
console.log(count);
count++;
}
- The condition is written backwards.
- The update moves
countaway from the condition. whileloops always need abreak.
Solution
b. count starts at 10 and grows, so count > 0 gets more true with every round. It should be count--.
2.4.6 Nested Loops
A loop is a statement, and the body of a loop can hold any statement — including another loop. A loop inside a loop is called a nested loop.
▶ Press Run to see the output…
What you should see:
row 1, col 1 row 1, col 2 row 1, col 3 row 1, col 4 row 2, col 1 row 2, col 2 row 2, col 3 row 2, col 4 row 3, col 1 row 3, col 2 row 3, col 3 row 3, col 4
Read the order carefully, because it is the thing beginners get wrong. The inner loop runs all the way through for every single round of the outer loop. The outer loop moves to row 2 only after the inner loop has finished all four columns.
A nested loop is a loop written inside the body of another loop. The inner loop completes all of its iterations for each single iteration of the outer loop.
Definition 2.4.5 — A nested loop is a loop written inside the body of another loop; the inner loop completes all of its iterations for each single iteration of the outer loop.
That gives you a way to count the work: 3 rows × 4 columns = 12 lines of output. Multiply, do not add.
Nested loops are the natural shape for anything with rows and columns.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
1 2 3 4 2 4 6 8 3 6 9 12 4 8 12 16
The inner loop builds one row as a string; the outer loop prints it and starts the next. \t is a tab character, which lines the columns up.
A nested loop is one loop drawn inside another loop's body. Literally -- the inner circuit sits between two boxes of the outer one.
Figure 2.4.4 — The multiplication table. The inner loop is a complete circuit sitting inside the outer loop's body; it runs to completion once per outer trip.
Trace one trip of the outer loop with your finger. You enter at line = "", go round the inner circuit four times, and only then reach print line. Four outer trips, four inner trips each -- sixteen visits to the line = line + a * b box, which is where "16 rounds of work" comes from without counting anything.
A nested loop is one loop drawn inside another loop's body. Literally -- the inner circuit sits between two boxes of the outer one.
Trace one trip of the outer loop with your finger. You enter at line = "", go round the inner circuit four times, and only then reach print line. Four outer trips, four inner trips each -- sixteen visits to the line = line + a * b box, which is where "16 rounds of work" comes from without counting anything.
break leaves only the inner loopThis one surprises people. A break in a nested loop stops the loop it is directly inside — not both.
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
What you should see:
i=1 j=1 i=2 j=1 i=3 j=1 Done.
The inner loop breaks at j === 2 every time, but the outer loop is untouched and starts a fresh inner loop for the next i. If you need to leave both, use a flag the outer loop can test:
▶ Press Run to see the output…
What you should see:
i=1 j=1 i=1 j=2 i=1 j=3 i=2 j=1 Done.
The && !stop in the outer condition is the && from Section 2.1.8 doing real work: the outer loop continues only while it has rounds left and nothing has asked it to stop.
Nested loops get expensive fast. Two nested loops over 1,000 items each is a million rounds — a noticeable pause. Three is a billion, and your program appears to hang. When a nested loop feels slow, count the multiplication before you look anywhere else.
1. How many times does the inner console.log run?
▶ Press Run to see the output…
- 8
- 15
- 5
Solution
b. 15. The inner loop runs 3 times for each of the outer loop's 5 rounds: 5 × 3.
Option a is the trap — you add the two counts instead of multiplying them.
2. In a nested loop, a break in the inner loop stops:
- Both loops.
- Only the inner loop.
- Only the outer loop.
Solution
b. Only the inner loop. The outer loop continues with its next round and starts the inner loop over.
Use nested loops to print a triangle of stars, one row at a time: row 1 has one star, row 2 has two, up to row 5.
* ** *** **** *****
▶ Press Run to see the output…
Solution
▶ Press Run to see the output…
Output:
* ** *** **** *****
The inner loop's condition is star <= row, not a fixed number — that is what makes each row longer than the last.
The loop below is meant to print each pair once, like 1-2, 1-3, 2-3. Instead it prints every pair twice and prints pairs like 1-1. Fix the inner loop's starting value.
for (let a = 1; a <= 3; a++) {
for (let b = 1; b <= 3; b++) {
console.log(a + "-" + b);
}
}
Type it into the editor and run it:
▶ Press Run to see the output…
Solution
Start the inner loop at a + 1 so it only ever looks at numbers after the current one.
▶ Press Run to see the output…
Output:
1-2 1-3 2-3
The inner loop's start does not have to be a constant — it can depend on the outer loop's counter, which is what makes this work.
Problem Set 2.4
2.4.1 Which loop fits better for printing every item in a list of 12 names, and why?
Solution
Step 1 — Identify the loop type: A for loop fits better.
Step 2 — Explain why: The list has a known length (12), so the number of repetitions is known before the loop starts. That is exactly the case where a for loop shines: it gathers the start, condition, and update on one line, making the fixed count obvious to any reader.
Answer: A for loop, because the number of repetitions (12) is known in advance.
2.4.2 Which loop fits better for shuffling a deck until the top card is an ace, and why?
Solution
Step 1 — Identify the loop type: A while loop fits better.
Step 2 — Explain why: You cannot know in advance how many shuffles it will take before an ace lands on top. The stopping point depends on the result of the work itself, not on a counter — which is precisely when a while loop is the right choice.
Answer: A while loop, because the number of shuffles needed is not known in advance.
2.4.3 How many times does this body run? Explain.
▶ Press Run to see the output…
Solution
Step 1 — Recall how do...while works: In a do...while loop, the body runs first and the condition is tested afterwards. So the body always runs at least once, no matter what the condition says.
Step 2 — Trace the execution: x starts at 0. The body runs once: "ran" prints and x becomes 1. Then the condition x < 0 is tested — 1 < 0 is false, so the loop ends.
Answer: The body runs exactly once, because a do...while tests its condition after running the body, guaranteeing at least one execution.
2.4.4 What does this print?
▶ Press Run to see the output…
Solution
Step 1 — Trace each round: The loop runs i from 1 to 5. When i === 3, the continue statement skips the rest of that round (the console.log) and jumps straight to the update i++.
Step 2 — Collect the printed values: Rounds with i = 1, 2, 4, 5 print normally; round i = 3 prints nothing.
1 2 4 5
Answer: It prints 1, 2, 4, 5 (each on its own line) — the value 3 is skipped by continue.
2.4.5 You are searching a list for the first out-of-stock item and want to stop as soon as you find one. Do you want break or continue? Why?
Solution
Step 1 — Match the goal to the statement: "Stop as soon as you find one" means you want to leave the loop entirely the moment the out-of-stock item appears.
Step 2 — Choose: break immediately ends the whole loop; continue would only skip one round and keep searching through the rest of the list for no reason.
Answer: break, because you want to stop searching entirely as soon as the first out-of-stock item is found.
2.4.6 Explain why this loop never ends, and fix it.
let count = 10;
while (count > 0) {
console.log(count);
count++;
}
▶ Press Run to see the output…
Solution
Step 1 — Diagnose the bug: count starts at 10 and the condition is count > 0. But the update is count++, so count grows: 10, 11, 12, … Every round makes count > 0 more true, so the condition never becomes false. This is cause #2 of infinite loops: the update moves the counter the wrong way.
Step 2 — Fix it: Change the update to count-- so count moves toward 0 and the condition can eventually fail:
▶ Press Run to see the output…
Output:
10 9 8 7 6 5 4 3 2 1
Answer: The loop never ends because count++ moves count away from the condition instead of toward it; changing count++ to count-- fixes it.
2.4.7 How many times does the inner console.log run?
▶ Press Run to see the output…
Solution
Step 1 — Count each loop's rounds: The outer loop runs for i = 1, 2, 3, 4, 5 — that is 5 rounds. For each outer round, the inner loop runs fully for j = 1, 2, 3 — that is 3 rounds.
Step 2 — Multiply: Nested work multiplies, it does not add:
$$5 \times 3 = 15$$Answer: The inner console.log runs 15 times (5 outer rounds × 3 inner rounds).
2.4.8 In a nested loop, which loop does a break in the inner loop stop?
Solution
Step 1 — Recall what break does: break immediately ends only the loop it is directly inside. It has no effect on any enclosing loop.
Step 2 — Apply to nesting: So a break in the inner loop stops just the inner loop. The outer loop continues with its next round and starts a fresh run of the inner loop. To exit both loops you need a flag variable the outer loop can test.
Answer: Only the inner loop stops; the outer loop keeps going.
2.4.9 Write a do...while loop that prints the numbers 10 down to 1.
▶ Press Run to see the output…
Solution
Step 1 — Set up the counter: Start at 10, since we print downward.
Step 2 — Write the loop: Print the current value, then decrement. Because it is a do...while, the body runs first and the test happens after — here the condition i >= 1 is true initially anyway, but the structure still guarantees at least one line even if it were not.
▶ Press Run to see the output…
Output:
10 9 8 7 6 5 4 3 2 1
Answer: The code above prints the numbers 10 down to 1 using a do...while loop.
2.4.10 Rewrite this for loop as a while loop with the same output.
for (let i = 2; i <= 10; i += 2) {
console.log(i);
}
▶ Press Run to see the output…
Solution
Step 1 — Identify the three parts of the for loop: Start: let i = 2; condition: i <= 10; update: i += 2 (add 2 each round). It prints 2, 4, 6, 8, 10.
Step 2 — Rebuild them in a while: Declare the start before the loop, keep the same condition in the while (...), and move the update into the last line of the body so every round still advances i.
▶ Press Run to see the output…
Output:
2 4 6 8 10
Answer: The while version above produces identical output: 2, 4, 6, 8, 10.
2.4.11 Write a loop over the numbers 1 to 30 that prints only those divisible by both 3 and 5. Use continue for the ones that do not qualify.
▶ Press Run to see the output…
Solution
Step 1 — Decide the skip test: A number qualifies if it is divisible by both 3 and 5 — equivalently, if i % 3 !== 0 || i % 5 !== 0, we should skip it with continue.
Step 2 — Write the loop: Loop i from 1 to 30; when the number fails either divisibility test, continue past the printing.
▶ Press Run to see the output…
Output:
15 30
Only 15 and 30 are divisible by both 3 and 5 in this range.
Answer: The code above prints 15 and 30 — the numbers from 1 to 30 divisible by both 3 and 5.
2.4.12 Write a while (true) loop that starts at 1, doubles each round, and breaks the first time the value passes 1000. Print the value that broke it.
▶ Press Run to see the output…
Solution
Step 1 — Set up the loop: Start value at 1. Use while (true) because we do not know in advance how many doublings it takes — the break is the deliberate exit.
Step 2 — Double and test: Each round, double value. If it now exceeds 1000, print it and break; otherwise keep looping.
▶ Press Run to see the output…
Trace: 1 → 2 → 4 → 8 → 16 → 32 → 64 → 128 → 256 → 512 → 1024. Since \(1024 > 1000\), the loop breaks there.
Answer: The loop prints 1024, the first power of 2 greater than 1000.
2.4.13 This loop is supposed to print the odd numbers from 1 to 9 but hangs instead. Explain why, then fix it.
let i = 0;
while (i < 10) {
if (i % 2 === 0) {
continue;
}
console.log(i);
i++;
}
Write your fixed version here:
▶ Press Run to see the output…
Solution
Step 1 — Explain the hang: When i is even (0, 2, 4, ...), the continue fires and jumps straight back to the top of the while loop — skipping both the console.log and the i++ line below it. Since i never changes, the condition i < 10 stays true forever. This is infinite-loop cause #3: a continue that skips the update.
Step 2 — Fix it: Move the update i++ to be the first thing inside the body, before any continue can skip it. Then adjust the check so the odd values 1 through 9 get printed:
▶ Press Run to see the output…
Output:
1 3 5 7 9
Answer: The hang happens because continue skips the i++ update, leaving i unchanged forever; moving i++ above the continue fixes it, and the fixed loop prints 1, 3, 5, 7, 9.
2.4.14 Use nested loops to print a 5-row triangle of stars where row 1 has five stars and row 5 has one.
▶ Press Run to see the output…
Solution
Step 1 — Plan the shape: Row 1 needs 5 stars, row 2 needs 4, ..., row 5 needs 1. So for outer counter row from 1 to 5, the inner loop should print \(6 - \text{row}\) stars.
Step 2 — Build each row with an inner loop: Accumulate stars into a string, then print the row after the inner loop finishes.
▶ Press Run to see the output…
Output:
***** **** *** ** *
Answer: The nested loops above print the inverted triangle: row 1 has five stars down to row 5 with one.
2.4.15 Explain in one sentence why two nested loops over 1,000 items each is much slower than two loops written one after the other.
Solution
Step 1 — Count the total rounds: Two nested loops over 1,000 items each perform \(1000 \times 1000 = 1{,}000{,}000\) rounds of inner work, because the inner loop completes fully for every single round of the outer loop.
Step 2 — Compare with sequential loops: Two loops written one after the other do \(1000 + 1000 = 2000\) rounds. One million versus two thousand is roughly a 500× difference in work.
Answer: Nested loops multiply their counts (1,000 × 1,000 = 1,000,000 rounds) while sequential loops add theirs (2,000 rounds), so nesting does about 500 times more work.
Key Terms
while loop -- A loop that tests its condition before each round; the right choice when the number of repetitions is not known in advance.
do...while loop -- A loop that runs its body first and tests afterwards, so the body always runs at least once. Ends with a semicolon.
break -- A statement that immediately ends the loop it is directly inside.
continue -- A statement that ends the current iteration and jumps to the next one, leaving the loop itself running.
Infinite loop -- A loop whose condition never becomes false, so it never finishes. Usually caused by a missing update, an update moving the wrong way, or a continue that skips the update.
Nested loop -- A loop inside the body of another loop; the inner loop completes fully for each single round of the outer.
Guard counter -- A temporary counter added while debugging that forces a suspect loop to stop after a fixed number of rounds.
Remainder operator (%) -- Gives what is left over after a division; n % 2 === 0 tests whether n is even.