LABORATORY 06

Statements (2) - Loop and Jump Structures

Duration: 2 hours Language: C / C++ Previous: Laboratory 5 PDF handout RO versiunea română

Loop structures let a sequence of statements run as long as a condition stays true. The three forms in C/C++ are equivalent in computing power, but each expresses a particular kind of repetition more naturally.

1Lab objectives

  • Choosing the right loop depending on the problem to solve
  • Understanding the difference between loops with an initial test and those with a final test
  • Correctly building the three components of the for statement
  • Using the break and continue statements
  • Identifying and avoiding infinite loops

2The three loops, compared

StatementCondition testMinimum executionsUsed when
whilebefore the body0the number of repetitions is not known in advance
do-whileafter the body1the body must run at least once (menus, validation)
forbefore the body0the number of repetitions is known or a range is being traversed
while - test before condition? body exit do-while - test after body condition? exit for - equivalent to while init; while (cond) { body; step; }
Fig. 1 - The flow difference between the three loop structures

3The while and do-while statements

syntax
while (expression)
    statement;

do
    statement;
while (expression);        // note: the semicolon here is mandatory

With while, the expression is tested first; if it is true (nonzero), the body runs, then it is re-evaluated. With do-while, the body runs before the first test, so at least once, regardless of the condition.

The condition must be able to changeThe value of the expression that controls the loop must be changed somewhere inside the body. If this does not happen, the loop runs forever, and the program hangs.

4The for statement

the structure of the three components
for (initialization; condition; step)
    statement;

for (int i = 0; i < 10; i++) { ... }
      │           │        └── runs AFTER every iteration
      │           └─────────── tested BEFORE every iteration
      └─────────────────────── runs ONCE, at the start

All three components are optional. for (;;) is a valid infinite loop, equivalent to while (1).

FormEffect
for (i = 0; i < n; i++)classic ascending traversal
for (i = n - 1; i >= 0; i--)descending traversal
for (i = 0, j = n; i < j; i++, j--)two indices, using the comma operator
for (;;)infinite loop

5Loop simulator

Change the three parameters and watch the iteration table: how many times the body runs, what values the counter takes, and what value it is left with after the loop ends. Set the step to 0 to see how an infinite loop is detected.

for - automatically generated iteration table

6Step-by-step execution

Watch how continue and break work in a loop that only sums the even numbers, stopping at the first negative value.

break and continue in action

7Jump statements

StatementEffectScope of action
breakexits the current loop or switchonly the innermost structure
continueskips to the next iterationonly the innermost loop
returnexits the function, returning a valuethe whole function
goto labelunconditional jump to a labelwithin the same function
exit(code)terminates the entire programthe whole program
About gotoAlthough it exists in the language, goto makes code hard to follow and maintain. The only use accepted in modern practice is a quick exit from deeply nested loops, toward a common resource-cleanup point.
break in nested loopsA break only exits the inner loop. To leave both loops, use a flag (bool found), move the code into a function with return, or - rarely - goto.

8Common mistakes

1. A semicolon after for or while for (i = 0; i < 10; i++); runs the loop ten times "doing nothing", and the block below it runs only once.
2. The "off by one" error for (i = 0; i <= n; i++) runs n + 1 iterations. When traversing an array of n elements, this overruns the bound by one position.
3. continue in do-while In do-while, continue jumps directly to the condition test. If incrementing the counter is placed after continue, it never runs, and the loop becomes infinite.
4. Modifying the counter inside the loop body Changing the control variable inside a for makes the behavior hard to follow and is a frequent source of loops that never end.

9Source code

average.c - while with an unknown number of values
#include <stdio.h>

int main(void)
{
    int n, i = 0;
    double value, sum = 0.0;

    printf("How many values? ");
    scanf("%d", &n);

    while (i < n) {
        printf("Value %d: ", i + 1);
        scanf("%lf", &value);
        sum += value;
        i++;                       // WITHOUT this line: an infinite loop
    }

    if (n > 0)
        printf("Arithmetic mean = %.4f\n", sum / n);
    else
        printf("No value entered\n");

    return 0;
}
menu.c - do-while for a repeated menu
#include <stdio.h>

int main(void)
{
    int choice;

    do {
        printf("\n--- MENU ---\n");
        printf("1. Add\n2. Delete\n3. Show\n0. Exit\n");
        printf("Choose: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1: printf("You chose add\n");     break;
            case 2: printf("You chose delete\n");  break;
            case 3: printf("You chose show\n");    break;
            case 0: printf("Goodbye!\n");          break;
            default: printf("Invalid option\n");
        }
    } while (choice != 0);        // the menu is shown at least once

    return 0;
}
primes.c - for with break and continue
#include <stdio.h>
#include <math.h>

int isPrime(int n)
{
    if (n < 2) return 0;
    for (int d = 2; d <= (int)sqrt(n); d++)
        if (n % d == 0)
            return 0;              // immediate exit from the function
    return 1;
}

int main(void)
{
    printf("Prime numbers up to 50:\n");

    for (int n = 1; n <= 50; n++) {
        if (!isPrime(n)) continue;     // skip the non-primes
        printf("%d ", n);
    }
    printf("\n");

    // multiplication table, with nested loops
    printf("\nMultiplication table 1-5:\n");
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5; j++)
            printf("%4d", i * j);
        printf("\n");                   // new line after each row
    }
    return 0;
}

10Code workshop

With loops, Step by step mode is the most useful tool: you see the counter growing and the condition being re-evaluated on every pass.

The same problem, three kinds of loops
#include <stdio.h>

int main(void)
{
    int i, s;

    s = 0;
    for (i = 1; i <= 5; i++) s += i;
    printf("with for      : 1+2+3+4+5 = %d\n", s);

    s = 0; i = 1;
    while (i <= 5) { s += i; i++; }
    printf("with while    : 1+2+3+4+5 = %d\n", s);

    s = 0; i = 1;
    do { s += i; i++; } while (i <= 5);
    printf("with do-while : 1+2+3+4+5 = %d\n", s);

    printf("\nThe 7 times table:\n");
    for (i = 1; i <= 10; i++)
        printf("  7 x %2d = %3d\n", i, 7 * i);
    return 0;
}
Exercise - prime numbers up to N
#include <stdio.h>

int main(void)
{
    int n, i, d, prime;

    printf("N = ");
    scanf("%d", &n);

    printf("Prime numbers up to %d:\n", n);
    for (i = 2; i <= n; i++) {
        prime = 1;

        /* Complete this: check whether i has any divisor between
           2 and i/2. If it does, set prime = 0 and exit the
           inner loop with break. */

        if (prime) printf("%d ", i);
    }
    printf("\n");
    return 0;
}

11Work tasks

  • Compute the arithmetic mean of N values read from the keyboard, using while.
  • Rewrite the same program with for and then with do-while; compare the readability.
  • Implement a repeating menu that only closes when option 0 is chosen.
  • Print all prime numbers up to 100, using continue.
  • Generate the multiplication table with nested loops and column alignment.
  • Compute the sum of the digits of an entered number, using while.
  • Reproduce the "off by one" error when traversing an array and observe what gets printed.
  • Write a loop that searches for a value in a matrix and exits both loops on the first match.

12Extended application

ExtensionWrite a program that prints Pascal's triangle with N rows, correctly aligned (each row centered relative to the one below it). Use only loops, no two-dimensional arrays - compute each binomial coefficient from the previous one, through successive multiplication and division. Check up to what value of N the results stay correct, before the int type overflows.

13Review questions

14Resources