CS U111 · Lab 4 · practice ladder

Loops, one rung at a time

Fourteen small programs in five rungs, each one idea, each with the exact output to check against and a solution folded away. The lab sheet goes from "here is a for loop" straight to problems that combine two or three ideas; this page is the rung in between. Every program here was compiled and run before it was published.

Start here · how to climb

Type every program yourself — do not read it and nod. The lab is mostly about getting past your own typing errors quickly, and that only comes from typing. Rules: (1) read the statement and write the three answers — state, stop, advance — on paper first; (2) type, compile with clang -Wall, run with the sample input, compare with the sample output character by character; (3) open the solution only after your version runs, to compare, not to copy; (4) move to the next rung when a rung's programs compile on the first or second try. Twenty minutes a day for a week beats one long evening. Then do the predict-the-output drill and only then the sheet.

On this page

  1. Rung 1 · fixed-count for loops
  2. Rung 2 · accumulate
  3. Rung 3 · eat a number digit by digit
  4. Rung 4 · stop on a condition, not a count
  5. Rung 5 · loops inside loops
  6. Then the sheet
Rung 1

Fixed-count for loops

You know how many times before you start. Three problems, each under ten lines. Goal: a for line you can write without thinking about where the semicolons go.

Problem 1

Print 1 to n on one line

The task

Read n. Print the numbers 1 to n on one line, separated by spaces.

Sample run (your input shown after the prompt):

Enter n: 5
1 2 3 4 5
State: i. Stop: i <= n. Advance: i++. Shape: for — the count is known.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n;
    printf("Enter n: ");
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

The printf("\n") after the loop is what ends the line; inside the loop there is no \n, which is why everything stays on one line.

Problem 2

The 7 times table

The task

Print the 7 times table from 7 × 1 to 7 × 10, one line per product, in the form 7 x 3 = 21.

Sample run (your input shown after the prompt):

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70
State: i. Stop: i <= 10. Advance: i++. No input needed.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    for (int i = 1; i <= 10; i++) {
        printf("7 x %d = %d\n", i, 7 * i);
    }
    return 0;
}

Debugging Exercise 1 on the sheet is this program with < 10 instead of <= 10. Type this one and you will never make that slip.

Problem 3

A row of n stars

The task

Read n. Print n asterisks on one line.

Sample run (your input shown after the prompt):

Enter n: 6
******
State: i. Stop: i < n (starting from 0) or i <= n (starting from 1) — both give n stars. Advance: i++.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n;
    printf("Enter n: ");
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        printf("*");
    }
    printf("\n");
    return 0;
}

Count the stars in your output against n. Off by one here is the single most common loop error; the fix is always in the pair (start value, comparison).

Rung 2

Accumulate

A variable outside the loop that the loop feeds. Goal: initialise it before the loop, update it inside, use it after — every time.

Problem 4

Sum of 1 to n

The task

Read n. Print the sum 1 + 2 + … + n.

Sample run (your input shown after the prompt):

Enter n: 100
Sum of 1 to 100 is 5050
State: i and an accumulator sum initialised to 0. Stop: i <= n. Advance: i++.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n, sum = 0;
    printf("Enter n: ");
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        sum += i;
    }
    printf("Sum of 1 to %d is %d\n", n, sum);
    return 0;
}

Debugging Exercise 3 on the sheet is this program with int sum; left uninitialised. Check: 5050 is the famous answer for 100.

Problem 5

Factorial

The task

Read n. Print n! = 1 × 2 × … × n.

Sample run (your input shown after the prompt):

Enter n: 6
6! = 720
State: i and an accumulator fact initialised to 1 (not 0 — multiplying by 0 kills everything). Stop: i <= n. Advance: i++.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n;
    long long fact = 1;
    printf("Enter n: ");
    scanf("%d", &n);
    for (int i = 2; i <= n; i++) {
        fact *= i;
    }
    printf("%d! = %lld\n", n, fact);
    return 0;
}

long long and %lld because 13! already overflows an int. Try 12 (479001600) and 13 with a plain int to see garbage appear.

Problem 6

Average of n numbers

The task

Ask how many numbers, then read that many and print their average to two decimal places.

Sample run (your input shown after the prompt):

How many numbers? 4
Number 1: 10
Number 2: 20
Number 3: 30
Number 4: 45
Average: 26.25
State: counter i, accumulator sum, the current input x. Stop: i <= n. Advance: i++. The scanf sits inside the loop.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n, x, sum = 0;
    printf("How many numbers? ");
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        printf("Number %d: ", i);
        scanf("%d", &x);
        sum += x;
    }
    printf("Average: %.2f\n", (double) sum / n);
    return 0;
}

The cast (double) sum / n is essential: 105 / 4 with two ints is 26, not 26.25. Integer division is the trap of this rung.

Rung 3

Eat a number digit by digit

The six-line while loop from the notes, three bodies. Goal: % 10 and /= 10 become reflexes; the sheet's Problem 1 is these three combined.

Problem 7

Count the digits

The task

Read n. Print how many digits it has.

Sample run (your input shown after the prompt):

Enter n: 4096
4096 has 4 digits
State: a copy temp of n and a counter. Stop: temp != 0. Advance: temp /= 10. Shape: while — you don't know the count in advance.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n, digits = 0;
    printf("Enter n: ");
    scanf("%d", &n);
    int temp = n;
    while (temp != 0) {
        digits++;
        temp /= 10;
    }
    printf("%d has %d digits\n", n, digits);
    return 0;
}

Work on a copy so n survives for the final message. Try 0: the loop body never runs and the program says "0 digits" — the zero-iteration case the sheet's §19 tells you to test.

Problem 8

Sum of the digits

The task

Read n. Print the sum of its digits.

Sample run (your input shown after the prompt):

Enter n: 4096
Digit sum of 4096 is 19
Same loop as Problem 7 with sum += temp % 10 in the body. % 10 hands you the last digit; /= 10 throws it away.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n, sum = 0;
    printf("Enter n: ");
    scanf("%d", &n);
    int temp = n;
    while (temp != 0) {
        sum += temp % 10;
        temp /= 10;
    }
    printf("Digit sum of %d is %d\n", n, sum);
    return 0;
}

Problems 7, 8 and 9 are the same six-line loop with a different body. The sheet's Problem 1 asks for all three at once — do them one at a time here first.

Problem 9

Reverse a number

The task

Read n. Print its digits in reverse order as a number.

Sample run (your input shown after the prompt):

Enter n: 4096
4096 reversed is 6904
Same loop again; the body is reversed = reversed * 10 + temp % 10: shift what you have left one place, drop the new digit into the units.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n, reversed = 0;
    printf("Enter n: ");
    scanf("%d", &n);
    int temp = n;
    while (temp != 0) {
        reversed = reversed * 10 + temp % 10;
        temp /= 10;
    }
    printf("%d reversed is %d\n", n, reversed);
    return 0;
}

Try 1200: the answer is 21, not 0021 — leading zeros do not exist in an int. Say that out loud if asked; it is correct, not a bug.

Rung 4

Stop on a condition, not a count

while with a sentinel, do-while for a menu. Goal: know where the read goes and where the test sits; the sheet's Problems 4 and 5 live here.

Problem 10

Read until zero

The task

Read numbers until the user types 0. Then print how many numbers were entered (not counting the 0) and their sum.

Sample run (your input shown after the prompt):

Enter numbers, 0 to stop:
5
8
-3
0
You entered 3 numbers with sum 10
State: the latest input x, plus count and sum. Stop: x != 0. Advance: the next scanf, at the bottom of the body. Shape: while with a sentinel.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int x, count = 0, sum = 0;
    printf("Enter numbers, 0 to stop:\n");
    scanf("%d", &x);
    while (x != 0) {
        count++;
        sum += x;
        scanf("%d", &x);
    }
    printf("You entered %d numbers with sum %d\n", count, sum);
    return 0;
}

Read once before the loop, then again at the end of every pass — "read, test, use, read". Put the scanf at the top of the body instead and the 0 gets counted.

Problem 11

A menu that repeats until Quit

The task

Show a two-item menu plus 0 to quit. Read a choice, act on it, and show the menu again — until the user chooses 0.

Sample run (your input shown after the prompt):

1. Say hello  2. Say bye  0. Quit
Choice: 2
Bye!
1. Say hello  2. Say bye  0. Quit
Choice: 7
Not a valid choice.
1. Say hello  2. Say bye  0. Quit
Choice: 1
Hello!
1. Say hello  2. Say bye  0. Quit
Choice: 0
Quitting.
Shape: do-while — the menu must be shown at least once before there is anything to test. Stop: choice != 0, tested after each pass.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int choice;
    do {
        printf("1. Say hello  2. Say bye  0. Quit\n");
        printf("Choice: ");
        scanf("%d", &choice);
        if (choice == 1)
            printf("Hello!\n");
        else if (choice == 2)
            printf("Bye!\n");
        else if (choice != 0)
            printf("Not a valid choice.\n");
    } while (choice != 0);
    printf("Quitting.\n");
    return 0;
}

This is the skeleton of the sheet's Problem 4 (PIN validator) and Problem 7 (pattern menu). The invalid-choice branch is the habit the sheet's §19 calls "test the bad input".

Rung 5

Loops inside loops

Rows outside, columns inside, newline between. Goal: predict the shape from where the \n is; the sheet's Problem 7 and Debugging Exercise 4 are this rung.

Problem 12

A rectangle of stars

The task

Read rows and columns. Print a rectangle of asterisks.

Sample run (your input shown after the prompt):

Enter rows and columns: 3 4
****
****
****
Outer loop: one pass per row. Inner loop: one star per column. The printf("\n") sits between the loops — after the inner one finishes, inside the outer one.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int rows, cols;
    printf("Enter rows and columns: ");
    scanf("%d %d", &rows, &cols);
    for (int r = 1; r <= rows; r++) {
        for (int c = 1; c <= cols; c++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

Where the \n goes decides everything. Inside the inner loop: one star per line. Outside both loops: one long line. Between them: a rectangle.

Problem 13

A right triangle

The task

Read n. Print a right-angled triangle of asterisks with n rows: 1 star, then 2, up to n.

Sample run (your input shown after the prompt):

Enter n: 4
*
**
***
****
Rectangle with one change: the inner loop runs to r, the current row number, instead of to a fixed width.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n;
    printf("Enter n: ");
    scanf("%d", &n);
    for (int r = 1; r <= n; r++) {
        for (int c = 1; c <= r; c++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}

Debugging Exercise 4 on the sheet is the rectangle mistakenly left as j <= n. Change n to r and the triangle appears — that is the "change exactly one variable" the sheet asks for.

Problem 14

A multiplication grid

The task

Read n. Print the n × n multiplication table as a grid, columns aligned.

Sample run (your input shown after the prompt):

Enter n: 4
   1   2   3   4
   2   4   6   8
   3   6   9  12
   4   8  12  16
Rectangle again, but the cell prints r * c. %4d pads each number to width 4, which is what keeps the columns straight.
Solution — open after yours runs
#include <stdio.h>
int main(void)
{
    int n;
    printf("Enter n: ");
    scanf("%d", &n);
    for (int r = 1; r <= n; r++) {
        for (int c = 1; c <= n; c++) {
            printf("%4d", r * c);
        }
        printf("\n");
    }
    return 0;
}

This is the sheet's Problem 7 pattern menu without the switch: rows outside, columns inside, newline between. After this rung the sheet's patterns are yours.

Then the sheet

Each rung is a piece of a sheet problem. When the rung is solid, the sheet problem is assembly, not invention:

RungSheet problems it unlocksWhat is still new there
1 · fixed countDebugging Exercise 1, Dry Runs 1 and 4break and continue
2 · accumulateProblem 6 (π series), Debugging Exercise 3alternating sign, double arithmetic
3 · digitsProblems 1 and 3, Debugging Exercise 2doing three things in one pass; repeating until one digit
4 · condition-controlledProblems 4 and 5, Dry Run 2an attempts counter in the condition; halving a range
5 · nestedProblem 7, Debugging Exercise 4, Dry Run 3a switch choosing which pattern; the inverted triangle

Problem 2 (binary) is the one sheet problem with no rung here — its trick (find the highest power of 2 first, then walk down) is its own idea, and the solutions page spends the most time on it for that reason.

Ask an AI well

"Give me a C loop problem exactly like Hanly & Koffman chapter 5, one idea only — a for loop that prints a pattern — with the sample output, and check my code when I paste it. Do not show me a solution first." · "Here is my digit-reversal loop and its output for 1200. Is the 21 correct or a bug? Explain in two lines." Keep to chapter 5; no arrays or functions yet.