TRT
Sign in

Foundations · Module 1 · Lesson 2 of 7

Repeating Yourself: for and while Loops

Learn how to repeat code with for and while loops, trace loop execution step by step, and avoid off-by-one errors and infinite loops.

FreeAbout 15 minutes

By the end you can

  • Write for loops to repeat code a known number of times
  • Write while loops to repeat while a condition is true
  • Trace loop iterations through variables and output
  • Identify and fix off-by-one errors and infinite loops

Builds on Making Decisions: if, else if, and else.

01 · A question first

You need to print the numbers 1 through 100. You could write 100 printf statements, but that is slow and error-prone. What if you need 1,000 numbers? Or a million? How does the computer repeat an action without you writing it out every time?

Make a guess, then step through the trace below to check it.

02 · Watch it run

Tracing a for loop that sums 1 through 5step 1 of 4
int sum = 0;for (int i = 1; i <= 5; i = i + 1) {    sum = sum + i;}printf("%d\n", sum);
  1. slot 0sum: 0(looked at in this step)
  2. slot 1i: 1(looked at in this step)
  3. slot 2iteration: 1

sum starts at 0, i starts at 1. The loop condition (i <= 5) is checked.

Machine work: init sum=0, i=1; check 1 <= 5 -> true

03 · The idea

Start with the problem

Suppose you need to print the numbers from 1 to 5, or add up every integer from 1 to 100. With only variables and printf, you would have to write the same statement over and over:

c
int sum = 1 + 2 + 3 + 4 + 5;

Writing five additions by hand is tedious; writing 10,000 additions is impossible. Worse, what if the upper limit n is typed by the user at runtime via scanf? You cannot write n lines of code when you do not even know what n is until the program runs.

To process arbitrary amounts of data, a program needs iteration: a way to write a block of code once and instruct the CPU to repeat it as long as a condition holds. C provides two primary loop constructs for this: the for loop and the while loop.

How the idea works

Every loop needs three pieces of machinery to do useful work and stop on time:

  1. A starting state (initialization): Setting up a counter or accumulator variable before the first repetition begins.
  2. A continuation test (condition): A boolean check evaluated before each repetition. If the test is true (non-zero), the loop body runs; as soon as the test becomes false (0), the loop terminates and execution continues on the line after the closing brace.
  3. A progress step (update): Advancing the counter or state at the end of each repetition so the loop moves closer to stopping.

The for loop: counting a known number of times

When you know in advance how many iterations you want—such as counting from 1 to n or walking across n elements—the for loop puts all three pieces of loop control right at the top inside parentheses, separated by semicolons:

c
int sum = 0;
for (int i = 1; i <= 5; i = i + 1) {
    sum = sum + i;
}
printf("Sum: %d", sum);

Look at the trace above to see the exact order in which the CPU executes those three parts:

  1. Initialization (int i = 1): Runs once when the loop is first entered. Along with sum = 0, this sets up step 1 of the trace.
  2. Condition check (i <= 5): Tested before every single iteration, including the very first one. Since 1 <= 5 is true, the CPU enters the loop body.
  3. Loop body (sum = sum + i;): Adds the current value of i into the accumulator sum.
  4. Update (i = i + 1, often written i++): Runs at the end of each iteration, right before jumping back to step 2 to re-test i <= 5.

In the trace above, i steps through 1, 2, 3, 4, and 5, accumulating sum values of 1, 3, 6, 10, and finally 15. After the fifth iteration adds 5, the update step increments i to 6. The condition 6 <= 5 evaluates to false (0), and the loop exits cleanly with sum == 15.

The while loop: repeating until an event happens

When you do not know in advance how many iterations will be needed—for example, dividing a number by 10 until no digits remain, or reading numbers from stdin until the user types 0—use a while loop:

c
int number = 4829;
int digits = 0;
 
while (number > 0) {
    number = number / 10;
    digits = digits + 1;
}
printf("Digits: %d", digits);  /* prints 4 */

A while loop has only the condition inside its parentheses. You write the initialization before the loop and the update inside the loop body. In fact, any for (init; cond; update) loop is equivalent to initializing first, testing while (cond), and running update at the bottom of the body.

Controlling loop flow early: break and continue

Sometimes you need to adjust a loop from inside its body:

  • break exits the loop immediately, jumping to the first statement after the loop's closing brace (for example, stopping a search the moment you find the target value).
  • continue skips the remaining lines of the current iteration and jumps straight to the update step (in a for loop) or condition test (in a while loop).

Why it is correct

How do you convince yourself—and a code reviewer—that a loop computes the right answer and never gets stuck? Computer scientists reason about loops using two properties:

  1. The loop invariant: A statement about your variables that holds true before each iteration begins and after each iteration finishes. In the trace above, right before testing i <= 5 on every step, sum always equals the sum of all integers from 1 up to i - 1. When the loop finally stops because i has reached 6, the invariant guarantees that sum holds the sum of integers from 1 to 6 - 1 = 5.
  2. Termination (progress toward the bound): Every iteration increases i by 1 while the upper bound 5 stays fixed. Because i starts at 1 and strictly increases by 1 on every step, i is guaranteed to reach 6 after exactly 5 iterations, forcing i <= 5 to become false.

What it costs

A loop executes its body once per iteration. If a loop runs from i = 1 to n and performs a constant number of basic operations (an addition, an increment, and a comparison) on each pass, its time complexity is proportional to n, written O(n).

  • For n = 5, the CPU executes 5 additions quickly.
  • For n = 1,000,000, the CPU executes one million additions; the exact time depends on the compiler, processor, and surrounding work.
  • Meanwhile, the loop only ever uses two integer variables (sum and i), so its space cost is constant—just 8 bytes of stack memory whether n is 5 or 500,000,000.

Pitfalls and variations

MistakeWhat goes wrongFix
for (int i = 0; i >= 0; i++)Condition i >= 0 stays true as i grows, creating an infinite loop (until integer overflow)Make sure the update moves i toward making the condition false (i < n)
Forgetting to update the variable in a while loopThe variable tested in while (n > 0) never changes, freezing the program in an infinite loopUpdate the loop variable on every path through the while body
Uninitialized accumulator (int sum;)sum = sum + i adds 1, 2, ... onto random stack garbageAlways initialize accumulators (int sum = 0; or int product = 1;) before the loop
Using continue in a while loop before the updateJumps back to the condition check and skips i++ at the bottom of the body, causing an infinite loopUse a for loop (where continue still runs the update expression) or update before continue

Where it is used

Loops drive almost every workload in computing: game engines run a while (running) loop 60 times per second to render frames, network servers loop continuously over incoming client requests, and data processing pipelines iterate over millions of array elements and file records.

In the next lesson, you will learn how to package loops and calculations into named functions so you can call them from anywhere in your program without repeating yourself.

04 · Prove it

Question 1 of 3 · answer from memory

What is the final value of sum after the trace above completes?

05 · Practice

Something wrong with this lesson? Report a problem

Not started

Sign in to save your learning progress.

Sign in to save