munotes®

for Loops

Chapter Twenty-Eight

Syllabus topic 1, "Control Flow: Statements and Blocks, If-Else, Else-If, Switch, Loops- While and For Loops Do-while, Break and Continue, Goto and Labels"

Pages 132 to 136 of 222

In one line

for (initialisation; condition; step) statement is a while loop with its three parts collected into one line, which is why it is the loop to use whenever you know how many passes there will be.

The form, and what it is equivalent to

for (initialisation; condition; step)
    statement

means exactly this:

initialisation;
while (condition) {
    statement
    step;
}

That equivalence is the whole chapter. Everything a for loop does follows from it, including the order the three clauses run in:

  1. Initialisation, once, before anything else.
  2. Condition, tested before every pass. If false, the loop ends.
  3. The body.
  4. The step, after the body, then back to 2.
#include <stdio.h>

int main(void)
{
    for (int i = 1; i <= 5; i++) {
        printf("%d cubed is %d\n", i, i * i * i);
    }

    printf("counting down: ");
    for (int i = 5; i >= 1; i--) {
        printf("%d ", i);
    }
    printf("\n");

    printf("in threes: ");
    for (int i = 0; i <= 20; i += 3) {
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}
1 cubed is 1
2 cubed is 8
3 cubed is 27
4 cubed is 64
5 cubed is 125
counting down: 5 4 3 2 1
in threes: 0 3 6 9 12 15 18

The counter declared in the header belongs to the loop and does not exist after it (chapter 21). That is the C99 form and the one to use. If your college compiler rejects it, it is set to C89: declare int i; above the loop and write for (i = 1; ...).

Any clause may be empty

All three are optional, and the semicolons are not.

#include <stdio.h>

int main(void)
{
    int i;

    i = 1;
    for (; i <= 3; i++) {                 /* no initialisation */
        printf("a%d ", i);
    }
    printf("\n");

    for (i = 1; i <= 3; ) {               /* no step: the body does it */
        printf("b%d ", i);
        i++;
    }
    printf("\n");

    for (i = 1; ; i++) {                  /* no condition: always true */
        if (i > 3) {
            break;
        }
        printf("c%d ", i);
    }
    printf("\n");

    i = 0;
    for (;;) {                            /* all three empty */
        i++;
        if (i > 3) {
            break;
        }
        printf("d%d ", i);
    }
    printf("\n");
    return 0;
}
a1 a2 a3
b1 b2 b3
c1 c2 c3
d1 d2 d3

for (;;) is the idiomatic deliberate infinite loop in C, and it means the same as while (1). Either is fine; for (;;) is what you will read in other people's code.

Two counters, with the comma operator

Chapter 18 said the comma operator's real home is a for header. Here it is.

#include <stdio.h>
#include <string.h>

int main(void)
{
    char word[] = "abcdefg";
    int n = (int) strlen(word);

    printf("before: %s\n", word);
    for (int i = 0, j = n - 1; i < j; i++, j--) {
        char t = word[i];
        word[i] = word[j];
        word[j] = t;
    }
    printf("after : %s\n", word);
    return 0;
}
munotes.in132

for Loops

before: abcdefg
after : gfedcba

Two counters walk towards each other and the loop stops when they meet. That is the standard way to reverse an array in place, and chapter 37 uses it on the palindrome test.

The practical: the Fibonacci series

MU's Practical 3(c). Each term is the sum of the two before it, starting 0 and 1.

#include <stdio.h>

int main(void)
{
    int n;

    printf("How many terms? ");
    if (scanf("%d", &n) != 1 || n < 1) {
        printf("\nThat was not a count of terms.\n");
        return 1;
    }

    printf("\n");
    long long a = 0, b = 1;
    for (int i = 1; i <= n; i++) {
        printf("%lld ", a);
        long long next = a + b;
        a = b;
        b = next;
    }
    printf("\n");
    return 0;
}
12
How many terms?
0 1 1 2 3 5 8 13 21 34 55 89

Read the three lines in the body: print the current term, work out the next one, then shift the pair along. The temporary next is necessary. Without it, a = b; b = a + b; would use the new a in the second line and give the wrong series.

long long rather than int, because the series passes two thousand million at the 47th term. Chapter 35 gives the same series recursively and shows why that version is unusable past about the 40th term.

The practical: patterns of asterisks

MU's Practical 2(c). This is what nested loops are for: the outer loop counts the rows and the inner loop draws one row.

#include <stdio.h>

int main(void)
{
    int n = 5;

    printf("1. a right triangle\n");
    for (int row = 1; row <= n; row++) {
        for (int col = 1; col <= row; col++) {
            printf("*");
        }
        printf("\n");
    }

    printf("\n2. an inverted triangle\n");
    for (int row = n; row >= 1; row--) {
        for (int col = 1; col <= row; col++) {
            printf("*");
        }
        printf("\n");
    }

    printf("\n3. a pyramid\n");
    for (int row = 1; row <= n; row++) {
        for (int space = 1; space <= n - row; space++) {
            printf(" ");
        }
        for (int col = 1; col <= 2 * row - 1; col++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
1. a right triangle
*
**
***
****
*****

2. an inverted triangle
*****
****
***
**
*

3. a pyramid
    *
   ***
  *****
 *******
*********
munotes.in133

for Loops

The pyramid is the one worth understanding rather than memorising. Row row needs n - row spaces and then 2 * row - 1 asterisks. Check it: row 1 gets 4 spaces and 1 asterisk, row 5 gets 0 spaces and 9 asterisks. Every pattern question is that same arithmetic: work out, for row row, how many of each thing, and the loops write themselves.

And the number patterns MU also sets:

#include <stdio.h>

int main(void)
{
    printf("Floyd's triangle\n");
    int value = 1;
    for (int row = 1; row <= 4; row++) {
        for (int col = 1; col <= row; col++) {
            printf("%d ", value);
            value++;
        }
        printf("\n");
    }

    printf("\nthe multiplication table of 1 to 5\n");
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= 5; j++) {
            printf("%4d", i * j);
        }
        printf("\n");
    }
    return 0;
}
Floyd's triangle
1
2 3
4 5 6
7 8 9 10

the multiplication table of 1 to 5
   1   2   3   4   5
   2   4   6   8  10
   3   6   9  12  15
   4   8  12  16  20
   5  10  15  20  25

for or while

Both can do anything the other can. Which to use is a question about what the loop is.

Use for whenUse while when
The number of passes is known before the loop startsIt is not
A counter walks a rangeThe loop ends on an event, such as input running out
Walking an arrayWaiting for a condition to change
The three parts are short enough to read on one lineThe condition is complex

The honest rule: a for loop says "this many times", a while loop says "until this happens". Choose the one that tells the truth about your loop.

What this does NOT mean

The step does not run before the first pass. Order is initialisation, condition, body, step.

The step does not run after the last body. It does: the step runs, then the condition fails. That is why the counter ends one past the last value used.

A for loop is not required to count. Any expression may be the step, and any condition may be the test.

The semicolons are not optional even when the clauses are. for (;;) has two.

for (int i = ...) is not universally available. It is C99. Some college machines compile as C89 and will reject it.

A nested loop's counters must not share a name. They may, and the inner one then shadows the outer (chapter 21), which breaks the outer loop's counting. Use row and col, not i and i.

Quick revision

  • for (init; condition; step) statement.
  • Order: init once, then condition, body, step, condition, body, step, and so on.
  • It is exactly init; while (condition) { statement step; }.
  • Any clause may be empty; the semicolons stay. for (;;) is a deliberate infinite loop.
  • The counter ends at the first value that failed the condition.
  • for (int i = ...) scopes the counter to the loop, and is C99.
  • The comma operator steps two counters: for (int i = 0, j = n - 1; i < j; i++, j--).
  • Nested loops: the outer counts rows, the inner draws one row.
  • Pyramid row row of n: n - row spaces then 2 * row - 1 asterisks.
  • Fibonacci needs a temporary for the next term, and long long past the 46th.
  • Use for for a known number of passes, while for an event.
munotes.in134

for Loops

Test yourself

1. In what order do the three clauses of a for loop run?

Initialisation once, then for each pass the condition, then the body, then the step.

2. Rewrite for (i = 0; i < n; i++) sum += a[i]; as a while loop.

i = 0;
while (i < n) { sum += a[i]; i++; }

3. What does for (;;) do?

Loops for ever: with no condition the test is treated as true. It is ended with a break or a return.

4. How many times does the inner printf run?

for (int i = 1; i <= 3; i++)
    for (int j = 1; j <= 4; j++)
        printf("*");

Twelve: three outer passes times four inner passes.

5. For a pyramid of n rows, how many spaces and asterisks does row row need?

n - row spaces and 2 * row - 1 asterisks.

6. Why does the Fibonacci loop need a temporary variable?

Because both a and b must change together. Writing a = b; b = a + b; uses the already-updated a in the second statement and produces the wrong series.

7. What is i after for (int i = 0; i < 5; i++) { }, and can you print it afterwards?

Inside the loop it would end at 5, but the name does not exist after the loop, so it cannot be printed. Declare i before the loop if you need its final value.

What can be asked on this, and how to answer it

"Explain the for loop with syntax and an example." Give the syntax, the order of the three clauses, and the while equivalent, which is the part that shows understanding. Then a counting example. Add that any clause may be empty.

"Write a program to print the Fibonacci series." Give this chapter's for version, name the temporary and say why it is needed, and mention the type limit.

munotes.in135

for Loops

"Write a program to print a pyramid of stars." Give the program and, more importantly, the arithmetic: n - row spaces and 2 * row - 1 asterisks. An examiner who asks for a different pattern is asking for the same method.

"Distinguish between for and while." Both are pre-tested loops and either can do the other's job. A for collects initialisation, condition and step into one header and suits a known number of passes; a while suits a loop that ends on an event. Give the mechanical equivalence as the closing line.

"What is a nested loop? Give an example." A loop inside another loop's body. The outer loop runs once per row, the inner once per item in that row, so the inner body runs the product of the two counts. Give the multiplication table or the right triangle.

munotes.in136

The rest of this subject

These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.

Report or request
Done!