Categories
Computer Science / Information Technology Language: C

Loops

Oftentimes we find ourselves writing programs to do repetitive tasks. After all, the use of a computer is that it can do the same task a million times a second with 0 margins of error. Loops play a very important role in achieving this objective. There are three types of loops C provides:

  1. for
  2. while
  3. do-while

These three types can be differentiated as entry controlled (for and while) and exit control (do-while) but more on this later.

For Loop

The for loop is the most popular way of using a loop instruction simply because of its ease. The syntax of the for loop is as follows:

for (initialisation ; condition ; updation)
{
      Statements to execute…
}

The following example illustrates a way to use for loop:

#include <stdio.h>
int main() 
{
    int i;
    for (i = 1 ; i <= 10 ; i++)
    printf("%d ", i);
    return 0;
}

The above program prints the first 10 natural numbers. The following steps elucidate how the for statement gets executed:

  • When the for statement is executed for the first time, the value of counter ‘i’ is set to an initial value 1. – Now the condition is checked. The condition set is i <= 10 which happens to be true for the iteration.
  • Since the condition is satisfied, the body of the loop, i.e., printf() in this case, is executed.
  • Once the body of the loop is executed, the update part of the for statement is executed where i gets incremented by 1 and then the condition is checked.
  • These iterations go on until the condition fails (or the control encounters a ‘break’ statement which we shall see in a short while).

Points to note

  • The scope of the variable ‘i’ is the main() function.
  • For loop is entry controlled loop: the condition is checked at the beginning of the loop and not at the end
  • The minimum number of times the body of the loop gets executed is zero. It is the case where the condition fails in the very first iteration.
  • The for loop allows us to specify three things about a loop in a single line, hence it is convenient to use:
    • Loop counter declaration/initialisation.
    • Loop termination condition.
    • Incrementation of loop counter at the end of each iteration of the loop.
  • The following flow chart should summarize the discussion:
for loop flow diagram

There is one more clean way to do it which is as follows:

#include <stdio.h>
int main()
{
    for (int i = 1 ; i <= 10 ; i++)
    printf("%d ", i);
    return 0;
}

Here, though the program produces the same output as earlier, the scope of the variable ‘i’ is just the for loop.
Similar to conditional statements such as if, else-if and if-else-if ladder, the default scope of any loop is the line immediately next to it. In the above example, it’s the printf() statement. If there are multiple sets of statements to be executed inside of the loops, one can use brackets
enclosure which is demonstrated in the following example:

#include <stdio.h>
int main() {
    for (int i = 1 ; i <= 10 ; i++)
    {
        printf("%d", i);
        printf("\n");
    }
    return 0;
}

It is important to note that the initialization, testing and incrementation part of a for loop can be replaced by any valid expression. For example:

int i = 0;
for (printf("Hello") ; i == 0 ; i++);

The above snippet will print “Hello”.

Multiple initialisations in for loop

The initialisation expression of the for loop can contain more than one statement separated by a comma. For example,

for ( i = 1, j = 2 ; j <= 10 ; j++ )

Multiple statements can also be used in the incrementation expression of for loop; i.e., you can increment (or decrement) two or more variables at the same time. However, only one expression is allowed in the test expression. This expression may contain several conditions linked together using logical operators.


The use of multiple statements in the initialisation expression also demonstrates why semicolons are used to separate the three expressions in the for loop. If commas had been used, they could not also have been used to separate multiple statements in the initialisation expression, without confusing the compiler.

While loops

Syntax:

Initialisation;
while (condition)
{
     statement1;
     statement2;
…
     statementn;
     updation;
}

}
Where,

  1. The initialisation is the declaration-assignment of a loop counter variable.
  2. Condition is the counter itself or a boolean expression involving the counter.
  3. Updation is an operation to alter the value of the loop counter variable.
  4. Statements inside the block of while constituting the ‘body’ of the while loop.

Points to note:

  • The statements in the body of the loop keep on getting executed till the condition remains true. When the condition is false, the control comes out of the loop and executes the first statement that follows the body of the while loop.
  • The condition can be replaced with any other valid expression which evaluates to a boolean true or false.
  • The default scope of the while loop is the single line following the loop statement. To override it, one must enclose the statements in a pair of parentheses as shown in the syntax.
  • Note that there is no semicolon at the end of the while loop. If there is a semi-colon, there is a high chance of the loop going into an infinite execution state as the updation of the loop counter is not happening.
  • If the condition of the while loop is a comparison, make sure that the elements being compared are having the same range bounds and the size of the elements is also the same. For example,
int i = 0;
while (i <= 32768) 
{
    printf("%d ", i);
    i++;
}
  • One might think that the above snippet would print integers from 0 to 32768 but the range of an int in a 32-bit compiler is till 32767 after which it becomes -32767 after increment, which certainly satisfies the condition. Hence this goes into an infinite loop.
  • It is not recommended to modify a variable inside of the while condition but one can do it without any syntactical error as shown in the following example:
int i = 0;
while (++i <= 10)
printf("%d ", i);
  • In this example, the value i pre increments in the condition of while. This prints integers from 1 to 10 inclusive. This is not recommended as it would be hard to read. One might easily assume that it prints from 0 to 10 inclusive by noticing that i is initialized to 0.
  • One more thing to notice in the previous example is that just by changing pre-increment to post-increment, the output would change from printing 1 to 10, to printing 1 to 11 inclusive.

The following flow chart should help in understanding the operation of while loop:

The following example prints the first 10 natural numbers using a while loop:

int n = 1;
while(n <= 10)
{
     printf("%d ", n);
     n++;
}

While loop is extensively used where there are a set of operations to be repeated a fixed number of times. For example, calculate the gross salaries of 10 different employees or convert cm to mm 10 times.

Do-while loop

The loops discussed till now are ‘entry controlled loops’ which means the condition is checked at the entry before executing the body of the loop for the first time. Ideally, a do-while loop is used when one does not know the number of iterations needed and the minimum number of times the body of the loop is to be executed is 1. The syntax is as follows:

do {
   statement(s);
} 
while( condition );

Notice that for a do-while loop, the pair of parenthesis is necessary. This is an ‘exit controlled loop’ as the condition is checked at the end of the loop. As discussed earlier, the do-while loop executes the statements in the body at least once while other loops the minimum number of
iterations are 0. This is illustrated clearly in the following 2 snippets with the same condition and body of the loop:

a. Using a do-while loop:

do {
    printf ( "Hello world") ;
} while ( 4 < 1 ) ;

Output: Hello world

b. Using while loop

while ( 4 < 1 )
    printf ( "Hello world") ;

The above loop produces no output.


The following example reads a number and prints the entered number’s square until the user wants:

do {
printf ( "Enter a number " ) ;
scanf  ( "%d", &num ) ;
printf ( "square of %d is %d", num, num * num ) ;
printf ( "\nWant to enter another number y/n " ) ;
scanf  ( " %c", &another ) ;
} while ( another == 'y' ) ;

The same output can be achieved using while and for. But the code wouldn’t be as ‘elegant’ as do-while.

The following is the flow chart of the do-while loop:

Nested loops

Nested loops are common in programming. Having one loop inside the block of another loop comes in handy for so many algorithmic applications such as sorting, reading matrix elements etc. It is perfectly common to place one loop inside the other to any level of nesting
and with various combinations of all 3 types of loops.

Consider one needs to print the following matrix:

00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33

It would be a terrible mess and a bad idea to do it without nested loops. The following snippet achieves the above output:

for (int i = 0 ; i < 4 ; i++)
{
    for (int j = 0 ; j < 4 ; j++)
        printf("%d%d ", i, j);
    printf("\n");
}

Notice that the scope of the loops is inherited, that is, by default, it’s the immediate line after the loop and it can be overridden with a pair of parenthesis.

The break statement

The break statement can be used with the loop to terminate the execution and continue with the execution of statements next to the loop. In other words, the break statement is used to ‘jump out of the loop’.

When a break is encountered inside any loop, control automatically passes to the first statement after the loop. A break is usually associated with an if conditional. Consider the following example which tells if the entered number is a prime number or not.

#include <stdio.h>
#include <math.h>
#include <stdbool.h>
int main()
{
    int n;
    bool isPrime = true;
    scanf("%d", &n);
    for (int i = 2 ; i <= sqrt(n) ; i++)
    {
        if (n % i == 0)
        {
            isPrime = false;
            break;
        }
    }
    printf("%s", isPrime ? "Prime" : "Not Prime");
    return 0;
}

In this program, the moment n % i evaluates to zero, (i.e. n is exactly divisible by i) the message “Not Prime” is printed and the control breaks out of the while loop. There are two ways the control could have reached outside the while loop:

  1. It jumped out because the number proved to be not a prime.
  2. The loop came to an end because the value of i became equal to the square root of n.

When the loop terminates in the second case, it means that there was no number between 2 and the square root of n that could exactly divide n. That is, n is indeed a prime. If this is true, the program should print out the message “Prime”. Notice that the statements above the break statement would get executed. And the statements after the break statement would get skipped.

The keyword break breaks the control only from the loop in which it is placed. Consider the following nested loop example:

#include <stdio.h>
int main()
{
    int i = 1 , j = 1;
    while ( i <= 10 ) {
        i++;
        while ( j <= 20 ) {
            j++;
            if ( j == 15 )
                break ;
            else
                printf ( "%d %d\n", i, j ) ;
        }
    }
    return 0;
}
2 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
2 13
2 14
3 16
3 17
3 18
3 19
3 20
3 21

In this program when j equals 15, the break takes the control outside the inner while only, since it is placed inside the inner while.

The continue statement

The continue statement takes the control to the beginning of the loop, bypassing the statements inside the loop, which have not yet been executed in that particular iteration. When a continue statement is encountered inside any loop, control automatically passes to the beginning of the loop. A continue is usually associated with an if.

#include <stdio.h>
int main() 
{
    int i, j ;
    for ( i = 1 ; i <= 2 ; i++ ) 
    {
       for ( j = 1 ; j <= 2 ; j++ )
       {
           if ( i == j )
               continue ;
           printf ( "%d %d\n", i, j ) ;
       }
    }
    return 0;
}

Output

1 2
2 1

Note that when the value of i equals that of j, the continue statement takes the control to the for loop (inner) bypassing the rest of the statements pending execution in the for loop (inner).

A continue statement in the do-while loop sends the control straight to the test at the end of the loop and not to the beginning of the loop.

Exercises

  1. Write a program to print all prime numbers from 1 to 300. (Hint: Use nested loops, break
    and continue)
  2. Write a program to generate all combinations of 1, 2 and 3.
  3. According to a study, the approximate level of intelligence of a person can be calculated using the following formula:
    i = 2 + ( y + 0.5 x )
    Write a program, which will produce a table of values of i, y and x, where y varies from 1 to 6, and, for each value of y, x varies from 5.5 to 12.5 in steps of 0.5.
  4. Write a program to print the following pattern:
  1. Write a program to read an integer number and print its table in the following format:
    12 * 1 = 12
    12 * 2 = 24

    12 * 10 = 120
  2. Write a program to print the following pattern:

    1
    2 3
    4 5 6
    7 8 9 10
  1. A machine is purchased which will produce an earning of Rs. 1000 per year while it lasts. The machine costs Rs. 6000 and will have a salvage of Rs. 2000 when it is condemned. If 12% per annum can be earned on alternative investments what would be the minimum life of the machine to make it a more attractive investment compared to alternative investments?
  1. Write a program in C to read x and the number of terms and display the sum of the
    series [ 1+x+x^2/2!+x^3/3!+….].
    Test data:
    x:3
    Terms:5
    Sum:16.375000

Leave a Reply

Your email address will not be published. Required fields are marked *

You cannot copy content of this page