Iteration Statements

Iteration statements (or loops) in C allow a program to execute a single statement multiple times. The execution of a single statement is controlled by a predicate that is evaluated at run-time. Sometimes this predicate is evaluated before executing the single statement (pre-evaluation) and sometimes it is evaluated after executing the single statement (post-evaluation). The predicate of an iteration statement is very important.
It is often claimed that programs spend 90% of their time executing 10% of their code. This characteristic is only possible if the time is spent in a subset of the programs iteration statements, or a small number of functions called within those statements. While there is a large body of published research on program performance, there is little evidence to back up this claim (one study found that 88% of the time was spent in 20% of the code, while analysis of some small embedded applications found that 90% of the time was spent in loops). It may be that researchers are attracted to applications which spend their time in loops because there are often opportunities for optimization. Most of existing, published, execution time measurements are based on engineering and scientific applications, for database oriented applications and operating systems loops have not been found to be so important.
An iteration statement causes a statement called the loop body to be executed repeatedly until the controlling expression compares equal to 0.
This defines the term loop body. The term loop is commonly used as a noun by developers to refer to constructs associated with iteration statements (which are rarely referred to as iteration statements by developers). For instance, the terms loop statement, or simply a loop are commonly used by developers. Execution of the loop may also terminate because a break, goto, or return statement is executed. The discussion on the evaluation of the controlling expression in an if statement is applicable here.
Some coding guideline documents recommend that loop termination only occur when the condition expressed in the controlling expression becomes equal to zero. A number of benefits are claimed to accrue from adhering to this recommendation. These include, readers being able to quickly find out the conditions under which the loop terminates (by looking at the loops controlling expression; which might only be a benefit for one form of reading) and the desire not to jump across the control flow. It is always possible to transform source code into a form where loop termination is decided purely by the control expression.
The repetition occurs regardless of whether the loop body is entered from the iteration statement or by a jump.
This is a requirement on the implementation. Some coding guideline documents recommend against jumping into the body of a loop. One argument is that a reader of the source may not notice that a loop could be entered in this way and makes a modification that fails to take this case into account (i.e., introduces a fault).
There are a variety of situations where jumping into the body of a loop may result in code that is less likely to contain faults and be less costly to maintain. Jumping into the body of a loop is rare and no data is available on the kinds of faults in which it plays a significant contributing factor. For this reason a no guideline recommending is given.
An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The rationale for this specification is the same as that given for the block implicitly created for a selection statement. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement. The rationale for this specification is the same as that given for the block implicitly created for the sub-statements of a selection statement.

Why do we do this?

  • we need to do the same work, but we don’t know how many times, e.g. print out payroll cheques for all employees
  • we want to read something in from the user, but they keep making a mistake
  • we want to do something several times, each slightly differently, e.g. draw a set of vertical lines, then a set of horizontal lines, to make a grid
The three iteration statements in C are while,dowhile and for

While

while (this condition is true){
    // Do the code inside the braces
}
The evaluation of the controlling expression takes place before each execution of the loop body.
The while statement evaluates a control expression before each execution of the loop body. If the control expression is true (nonzero), the loop body is executed. If the control expression is false (0), the while statement terminates. The While loop looks like an If statement. The difference is, when we reach the bottom of the loop, we go back to the top and start again. The code inside the braces (known as the loop body) is executed. While the condition stays true. Implications of this:
  • the loop body may never be executed, if the condition is initially false
  • if the condition is initially true, but never changes to false, we will loop forever!
  • therefore, the condition must somehow be changed inside the loop
#include <stdio.h>
int main(void){
    int LIMIT = 5;
    int count = 1;
    while (count<=LIMIT){
        printf("While loop executing %d\n", count );
        count++;
    }
    return 0;
}
Comments on the Example – The condition is true before the loop (1 <= 5). The condition is modified inside the loop (count++). Net result: The numbers 1 to 5 are printed on separate lines. Even though the code in the loop body is the same, the result of each loop is different is printed out on the screen each time.
Implication: the value of the variables used in the loop are important, they affect how the code executes.
Why do developers choose to use a while statement rather than for statement? Technically a loop can be written using either kind of statement. Both forms of iteration statement are likely to involve initializing, testing, and modifying one or more objects that systematically change over successive iterations. The for statement places these three components in a contiguous, visibly prominent, location. In both cases the choice of for/while involves a process of algorithmic problem classification.

Do – While

    do{
        // Do the code inside the braces
    }while (this condition is true);
The evaluation of the controlling expression takes place after each execution of the loop body.
The loop body of a do statement is always executed at least once. The benefits associated with having side effects in the controlling expression of a while statement are not applicable to a do statement (because the loop is always executed at least once). Given that the use of a do statement is relatively rare and that developers are likely to be familiar with the side effect idioms that occur in controlling expressions, no guideline recommendation is given here.
The Do loop is like the While loop, except that the loop body will execute once before the condition is tested. This can be very useful, when you need the body to execute at least once. Say we want to read numbers from the user, but they have to be in a certain range, e.g 1 to 100, with 0 being a sentinel value. We want to loop while they keep making mistakes. We want to get at least one number before we test it for validity.
Note: The Do loop ends with a semicolon.

For

    for (expression1; expression2; expression3) {
        statement;
    }
The for statement makes it more convenient to count iterations of a loop. The For loop is used when we know the number of times to loop, or the range of values to loop over.
Loop unrolling is the process of decreasing the number of iterations a loop makes by duplicating the statement in the loop body. Loop unrolling reduces the number of jumps performed and by increasing the number of statement in the loop body creates optimization opportunities. When the iteration count is not exactly divisible by the loop body unrolling factor copies of the loop body may need to occur before the start, or after the end, or the loop statement.
At the minimum, loop unrolling requires knowing the number of loop iterations and the amount by which the loop control variable is incremented, at translation time. Implementations often place further restrictions on loops before that they unroll.
Arbitrary amounts of loop unrolling does not necessarily guarantee improved performance. Duplicating the loop body increases code size, which decreases the probability that all of the loop body instructions will fit within the processor’s instruction cache. Unless optimizes take into account the size of a processor’s instruction cache when evaluating the cost effectiveness of loop unrolling they can end up reducing, rather than increasing, program performance.
Writers of coding guideline documents often regard the components of a for statement as having attributes that other loop statements don’t have. While it can be argued that many of these authors have simply grafted onto C concepts that only exist in other languages, if a sufficient number of developers associate these attributes with for statements then they become part of the culture of C and need to be considered here.
Note: A loop control variable shall not be modified during the execution of the body of a for statement.
In many books of C the for statement is described as for(initialization; test; increment){ /* code */ }
The initialization statement is executed exactly once before the first evaluation of the test condition. Typically, it is used to assign an initial value to some variable, although this is not strictly necessary. The initialization statement can also be used to declare and initialize variables used in the loop.
The test expression is evaluated each time before the code in the for loop executes. If this expression evaluates as 0 (false) when it is checked (i.e. if the expression is not true), the loop is not (re)entered and execution continues normally at the code immediately following the FOR loop. If the expression is nonzero (true), the code within the braces of the loop is executed.
After each iteration of the loop, the increment statement is executed. This often is used to increment the loop index for the loop, the variable initialized in the initialization expression and tested in the test expression. Following this statement execution, control returns to the top of the loop, where the test action occurs. If a continue statement is executed within the for loop, the increment statement would be the next one executed.
Advertisements
Tagged , ,
%d bloggers like this: