Jump to content

Loop (statement)

From Wikipedia, the free encyclopedia
(Redirected from For loop)

In computer programming, a loop is a control flow statement that allows code to be executed repeatedly; usually with minor alterations between repetitions. Loops can be used to perform a repeated action on all objects in a collection, or to implement a long lived program.

Overview

[edit]

Loops are a feature of high-level programming languages. In low-level programming languages the same functionality is achieved using jumps. When a program is compiled to machine code, looping may be achieved using jumps; but some loops can be optimized to run without jumping.[citation needed]

A conditional loop typically consists of a condition and a body. The body is code that is run repeatedly until the condition becomes false.

While loop

[edit]
While loop flow diagram

In a while loop the condition is initially checked, and if it is true the body is run. This is repeated until the condition is false. While loops are commonly formatted in manner similar to

while condition do
    body
repeat

Instead of the keywords do and repeat others methods are sometime use to indicate where the body begins and ends, such as curly braces[citation needed] or whitespace.[citation needed]

A while consists of a block of code and a conditional expression.[1] The conditional is evaluated, and if true,[1] the block of code is executed. This repeats until the conditional becomes false. Because the while loop checks the conditional before the block is executed, the control structure is also known as a pre-test loop. In contrast, do-while loop tests the conditional after the block.

For example, in the languages C, Java, C#,[2] Objective-C, and C++, (which use the same syntax in this case), the code fragment

int x = 0;
while (x < 5) {
    printf ("x = %d\n", x);
    x++;
}

first checks whether x is less than 5, which it is, so the loop body is entered, where printf() is called and x is incremented by 1. After completing the statements in the loop body, the condition, (x < 5), is checked again, and the loop is executed again. This process repeats until x has the value 5.

The condition can always valuate as true to create an infinite loop. In this case, there may be a early-exit control structure (such as a break statement) that controls termination of the loop. For example:

while (true) {
    // do complicated stuff
    if (someCondition)
        break;
    // more stuff
}

Do while loop

[edit]
Do While loop flow diagram

The do-while construct consists of a process symbol and a condition. First the code within the block is executed. Then the condition is evaluated. If the condition is true the code within the block is executed again. This repeats until the condition becomes false.

Do-while loops check the condition after the block of code is executed. This control structure can be known as a post-test loop. This means the do-while loop is an exit-condition loop. However a while loop will test the condition before the code within the block is executed.

This means that the code is always executed first and then the expression or test condition is evaluated. This process is repeated as long as the expression evaluates to true. If the expression is false the loop terminates. A while loop sets the truth of a statement as a necessary condition for the code's execution. A do-while loop provides for the action's ongoing execution until the condition is no longer true.

It is possible and sometimes desirable for the condition to always evaluate to be true. This creates an infinite loop. When an infinite loop is created intentionally there is usually another control structure that allows termination of the loop. For example, a break statement would allow termination of an infinite loop.

Some languages may use a different naming convention for this type of loop. For example, the Pascal and Lua languages have a "repeat until" loop, which continues to run until the control expression is true and then terminates. In contrast a "while" loop runs while the control expression is true and terminates once the expression becomes false.

Equivalent constructs

[edit]
do {
    do_work();
} while (condition);

is equivalent to

do_work();

while (condition) {
    do_work();
}

In this manner, the do ... while loop saves the initial "loop priming" with do_work(); on the line before the while loop.

As long as the continue statement is not used, the above is technically equivalent to the following (though these examples are not typical or modern style used in everyday computers):

while (true) {
    do_work();
    if (!condition) {
        break;
    }
}

or

LOOPSTART:
    do_work();
    if (condition) goto LOOPSTART;

For loop

[edit]
Flow diagram of a for loop that prints five asterisks.

A for loop has two parts: a header and a body. The header defines how the loop iterates, and the body is the code executed once per iteration. The header often declares a loop variable which can be used in the body to know which iteration of the loop is being executed. A relatively simple for loop iterates for a fixed number of times. For example, the following C for loop declares a loop variable i and prints its value as it increments from 0 to 1 to 2:

for (int i = 0; i < 3; ++i) {
    printf("%d", i);
}

Depending on programming language, various keywords are used to denote a for loop. For example, descendants of ALGOL use for,[3] while descendants of Fortran use do and COBOL uses PERFORM VARYING.

Variations

[edit]
For loop illustration, from i=0 to i=2, resulting in data1=200

Generally, a for loop falls into one of the following categories:

Numeric

[edit]

A numeric for loop increments a control variable from a start value to and end value. In languages such as ALGOL, Simula, BASIC, Pascal, Modula, Oberon, Ada, MATLAB, OCaml, and F# it looks like:

for i = first to last do statement

Some languages support an optional step value (increment or decrement). Some languages require a separate declaration of the control variable.

3 part

[edit]

A 3-part for loop, popularized by C, has the following parts separated by semi-colons: initialization (loop variant), condition, and advancement to the next value. Each part is optional and can be blank. This syntax came from B programming language and was originally invented by Stephen C. Johnson.[4] In the initialization part, variables can be prepared for the loop. The condition part checks a condition and exits the loop if false, even if the loop is never executed. If the condition is true, then the loop's block of is executed. The advancement to the next iteration part is performed each time the block is executed.

The following Java code is a C-style numeric loop that prints the numbers from 0 to 99.

for (int i = 0; i < 100; ++i) {
    System.out.printf("%d", i );
}

This form is often used like the numeric for loop, but is more flexible and can be used for other patterns. For example, for (start(); done(); next()) calls functions instead of using a control variable. The pattern of an infinite loop is implemented as for (;;).

Iterator-based

[edit]
foreach loops are almost always used to iterate over items in a sequence of elements.

A foreach loop enumerates the items of a sequence. It usually uses an implicit or explicit iterator, in which the loop variable represents each value of the sequence. The following Python code shows a foreach loop. items is either a data collection that supports implicit iteration, or may be an iterator itself.

for item in items:
    do_something(item)

This type of loop avoids potential off-by-one errors and makes code simpler to read.[citation needed]

Vectorized

[edit]

Some languages offer a for loop that acts as if processing all iterations in parallel, such as the for all keyword in Fortran 95 which has the interpretation that all right-hand-side expressions are evaluated before any assignments are made, as distinct from the explicit iteration form. For example, in the for statement in the following pseudocode fragment, when calculating the new value for A(i), except for the first (with i = 2) the reference to A(i - 1) will obtain the new value that had been placed there in the previous step. In the for all version, however, each calculation refers only to the original, unaltered A.

for     i := 2 : N - 1 do A(i) := [A(i - 1) + A(i) + A(i + 1)] / 3; next i;
for all i := 2 : N - 1 do A(i) := [A(i - 1) + A(i) + A(i + 1)] / 3;

The difference may be significant.

Loop counter

[edit]

A loop counter is a control variable that controls the iterations of a loop (a computer programming language construct). It is so named because most uses of this construct result in the variable taking on a range of integer values in some orderly sequences (for example., starting at 0 and ending at 10 in increments of 1)

Loop counters change with each iteration of a loop, providing a unique value for each iteration. The loop counter is used to decide when the loop should terminate and for the program flow to continue to the next instruction after the loop.

A common identifier naming convention is for the loop counter to use the variable names i, j, and k (and so on if needed), where i would be the most outer loop, j the next inner loop, etc. The reverse order is also used by some programmers. This style is generally agreed to have originated from the early programming of Fortran[citation needed], where these variable names beginning with these letters were implicitly declared as having an integer type, and so were obvious choices for loop counters that were only temporarily required. The practice dates back further to mathematical notation where indices for sums and multiplications are often i, j, etc. A variant convention is the use of duplicated letters for the index, ii, jj, and kk, as this allows easier searching and search-replacing than using a single letter.[5]

Additional semantics and constructs

[edit]

Use as infinite loops

[edit]

This C-style for loop is commonly the source of an infinite loop since the fundamental steps of iteration are completely in the control of the programmer. When infinite loops are intended, this type of for loop can be used (with empty expressions), such as:

for (;;) {
    // loop body
}

This style is used instead of infinite while (true) loops to avoid a type conversion warning in some C/C++ compilers.[6] Some programmers prefer the more succinct for (;;) form over the semantically equivalent but more verbose while (true) form.

Loop variable scope and semantics

[edit]

Different languages specify different rules for what value the loop variable will hold on termination of its loop, and indeed some hold that it "becomes undefined". This permits a compiler to generate code that leaves any value in the loop variable, or perhaps even leaves it unchanged because the loop value was held in a register and never stored in memory. Actual behavior may even vary according to the compiler's optimization settings, as with the Honeywell Fortran66 compiler.

In some languages (not C or C++) the loop variable is immutable within the scope of the loop body, with any attempt to modify its value being regarded as a semantic error. Such modifications are sometimes a consequence of a programmer error, which can be very difficult to identify once made. However, only overt changes are likely to be detected by the compiler. Situations, where the address of the loop variable is passed as an argument to a subroutine, make it very difficult to check because the routine's behavior is in general unknowable to the compiler unless the language supports procedure signatures and argument intents. Some examples in the style of pre-Fortran-90:

DO I = 1, N
  I = 7 !Overt adjustment of the loop variable. Compiler should complain
  Z = ADJUST(I) !Function "ADJUST" might alter "I", to uncertain effect.
  PRINT *, (A(I), B(I), I = 1, N, 2) !Implicit for loop to print odd elements of arrays A and B, reusing "I"... Compiler should complain.
  PRINT *, I                         ! What value will be presented?
END DO! How many times will the loop be executed?

A common approach is to calculate the iteration count at the start of a loop (with careful attention to overflow as in for i:= 0: 65535 do ... ; in sixteen-bit integer arithmetic) and with each iteration decrement this count while also adjusting the value of I: double counting results. However, adjustments to the value of I within the loop will not change the number of iterations executed.

Still, another possibility is that the code generated may employ an auxiliary variable as the loop variable, possibly held in a machine register, whose value may or may not be copied to I on each iteration. Again, modifications of I would not affect the control of the loop, but now a disjunction is possible: within the loop, references to the value of I might be to the (possibly altered) current value of I or to the auxiliary variable (held safe from improper modification) and confusing results are guaranteed. For instance, within the loop a reference to element I of an array would likely employ the auxiliary variable (especially if it were held in a machine register), but if I is a parameter to some routine (for instance, a print-statement to reveal its value), it would likely be a reference to the proper variable I instead. It is best to avoid such possibilities.

Adjustment of bounds
[edit]

Just as the index variable might be modified within a for loop, so also may its bounds and direction. But to uncertain effect. A compiler may prevent such attempts, they may have no effect, or they might even work properly - though many would declare that to do so would be wrong. Consider a statement such as

for i := first : last : step do
  A(i) := A(i) / A(last);

If the approach to compiling such a loop was to be the evaluation of first, last and step and the calculation of an iteration count via something like (last - first)/step once only at the start, then if those items were simple variables and their values were somehow adjusted during the iterations, this would have no effect on the iteration count even if the element selected for division by A(last) changed.

Early exit and continuation

[edit]

Some languages may also provide supporting statements for altering how a loop's iteration proceeds. Common among these are the break statement, which terminates the current loop the program is in, and the continue statement, which skips to the next iteration of the current loop. These statements may have other names; For example in Fortran 90, they are called exit and cycle.[citation needed]

A loop can also be terminated by returning from the function within which it is being executed.

In the case of nested loops, the break and continue statements apply to the inner most loop. Some languages allow loops to be labelled. These statements can then be applied to any of the loops in which the program is nested.

outer_loop: (This is a label for the outermost loop)
for 1 ≤ i ≤ 2 do
    for 1 ≤ j ≤ 2 do
        display(i, j)
        if i = 2
            contine outer_loop
        end if
    repeat
repeat
(This nested loop displays the pairs (1, 1), (1, 2), and (2, 1))

See also

[edit]

References

[edit]
  1. ^ a b "The while and do-while Statements (The Java Tutorials > Learning the Java Language > Language Basics)". Dosc.oracle.com. Retrieved 2016-10-21.
  2. ^ "while (C# reference)". Msdn.microsoft.com. Retrieved 2016-10-21.
  3. ^ Wirth, Niklaus (1973). "Preface". Systematic Programming: An Introduction. Prentice-Hall. pp. xiii. ISBN 0138803692.
  4. ^ Thompson, Ken. VCF East 2019 – Brian Kernighan interviews Ken Thompson. YouTube. Archived from the original on 2021-12-12. Retrieved 2020-11-16. I saw Johnson's semicolon version of the for loop and I put that in [B], I stole it.
  5. ^ http://www.knosof.co.uk/vulnerabilities/loopcntrl.pdf Analysis of loop control variables in C
  6. ^ "Compiler Warning (level 4) C4127". Microsoft. Retrieved 29 June 2011.