Definitions of Loop | For loop in details | While Loo in details | Do while Loop in Details | Use of Loop | What is Loop

A loop  is a kind of control structure in high-level programming languages , designed to organize the repeated execution of a set of instructions . Also, a loop can be called any sequence of instructions repeatedly executed, organized in any way (for example, using a conditional jump )

Definitions of Loop | What is Loop in software programming 

A sequence of instructions designed to be executed repeatedly is called a loop body . A single execution of a loop body is called an iteration . The expression that determines whether the iteration will be executed again or the loop will end is called an exit condition or a loop termination condition (or a continuation condition , depending on how its truth is interpreted – as a sign of the need to terminate or continue the loop). The variable storing the current iteration number is called the loop iteration counter or simply the loop counter.… The loop does not necessarily contain a counter, the counter does not have to be one – the condition for exiting the loop can depend on several variables changed in the loop, or it can be determined by external conditions (for example, the onset of a certain time), in the latter case, the counter may not be needed at all.

Execution of any loop includes initial initialization of the loop variables, checking the exit condition, executing the loop body, and updating the loop variable at each iteration. In addition, most programming languages ​​provide means for early control of the loop, for example, loop termination statements, that is, exiting the loop regardless of whether the exit condition is true (in C language  – break) and iteration skip operators (in C language – continue).

Types of Loops

 Unconditional loops

  • For Loop
  • While Loop
  • Do While loop

Sometimes programs use loops, the exit from which is not provided by the logic of the program. Such Loops are called unconditional, or endless. Due to their atypical nature, programming languages ​​do not provide special syntactic tools for creating infinite loops, therefore such loops are created using constructions designed to create ordinary (or conditional ) loops. To ensure infinite repetition, the condition check in such a loop is either absent (if the syntax allows, as, for example, in the loop LOOP … END LOOP of the Ada language ), or is replaced by a constant value ( while true do …in Pascal ). In the C language , a loop for (;;)with unfilled sections or a loop is used while (1).

Loop with precondition

A loop with a precondition is a loop that is executed as long as a certain condition specified before its beginning is true. This condition is checked before the loop body is executed, so the body may not be executed even once (if the condition is false from the very beginning). In most procedural programming languages, it is implemented by the while statement , hence its second name – while-loop. In Pascal, a preconditioned loop looks like this:

while  < condition >  do
begin
< loop body  > end ;

In C language :

while ( < condition > ) {
< loop body >
}

Loop with postcondition

A loop with a postcondition is a loop in which the condition is checked after the loop body is executed. Hence it follows that the body is always executed at least once. In Pascal, this loop is implemented by the operator repeat.. until ; in C – do…while.

In Pascal, a postcondition loop looks like this:

repeat

< loop body  > until < exit condition >

In C language:

do {

< loop body >

} while ( < condition for continuing the loop > )

There are differences in the interpretation of a loop condition with a postcondition in different languages. In Pascal and the languages ​​descended from it, the condition of such a Loop is interpreted as an exit condition (the Loop ends when the condition is true, in Russian terminology such Loops are also called “Loop before”), and in C and its descendants – as a continuation condition (the Loop ends when the condition is false, such loops are sometimes called “bye loop”).

Loop with an exit from the middle

A loop out of the middle is the most common form of a conditional loop. Syntactically, such a loop is formatted using three constructs: the beginning of the loop, the end of the loop, and the command to exit the loop. The start construct marks the point in the program where the body of the loop begins, and the end construct marks the point where the body ends. Inside the body, there must be a command to exit the loop, when executed, the loop ends and control is transferred to the statement following the end of the loop construction. Naturally, for the loop to be executed more than once, the exit command should not be called unconditionally, but only when the loop exit condition is met.

The fundamental difference between this type of loop and those considered above is that the part of the loop body located after the start of the loop and before the exit command is always executed (even if the loop exit condition is true at the first iteration), and the part of the loop body located after the exit command is not executed on the last iteration.

It is easy to see that using a loop with an exit from the middle, you can easily model both a loop with a precondition (by placing an exit command at the beginning of the loop body) and a loop with a postcondition (by placing an exit command at the end of the loop body).

Some programming languages ​​contain special constructs for organizing a loop with an exit from the middle. So, in the Ada language , a construct LOOP … END LOOPand an exit command are used for this, EXITor EXIT WHEN:

LOOP

…  Part  of the  loop

body EXIT  WHEN  < exit condition  > ; … Part of the body of the loop IF < exit condition > THEN EXIT ; END ; … Body part of the END LOOP loop :

Here, inside the loop, there can be any number of exit commands of both types. The exit commands themselves do not fundamentally differ; they EXIT WHEN are usually used when only the exit condition is checked, but simply EXIT when the loop is exited in one of the variants of a complex conditional operator.

In languages ​​where such constructs are not provided, a loop with an exit from the middle can be modeled using any conditional loop and an early exit from the loop (such as break in C, exit in Turbo Pascal, etc.), or the unconditional operator transition goto .

Counter Loop (or Loop for)

 A loop with a counter is a loop in which a variable changes its value from a given initial value to its final value with some step, and for each value of this variable, the body of the loop is executed once. In most procedural programming languages, it is implemented by an operator for, which specifies the counter (the so-called “loop variable”), the required number of passes (or the limit value of the counter) and, possibly, the step with which the counter changes. For example, in the Oberon-2 language, such a Loop looks like this:

FOR v: = b TO e BY s DO

… the body of the loop

END

here v is the counter, b is the initial value of the counter, e is the limit value of the counter, s is the step).

The question about the value of a variable at the end of a loop in which this variable was used as a counter is ambiguous. For example, if a Pascal program contains a construction of the form:

i  : =  100 ;

for  i  : =  0  to  9  do

begin

…  loop body  end ; k : = i ;

The question arises: what value will be eventually assigned to the variable k: 9, 10, 100, maybe something else? What if the Loop ends ahead of schedule? The answers depend on whether the counter value is incremented after the last iteration and whether the translator changes this value additionally. Another question: what happens if a new value is explicitly assigned to the counter inside the loop? Different programming languages ​​solve these issues in different ways. In some, the behavior of the counter is clearly regulated. In others, for example, in the same Pascal, the language standard does not define either the final value of the counter, or the consequences of its explicit change in the loop, but does not recommend changing the counter explicitly and using it at the end of the loop without reinitialization. A Pascal program that ignores this recommendation may produce different results when executed on different systems and using different translators.

The issue in the Ada and Kotlin languages ​​has been radically resolved : the counter is considered described in the header of the loop, and outside of it simply does not exist. Even if the name of the counter is already used in the program, a separate variable is used inside the loop as the counter. It is forbidden to explicitly assign any values ​​to the counter; it can only be changed by the internal mechanism of the loop operator.

As a result, the construction in Ada:

i  : =  100 ;

for  i  in  ( 0 .. 9 )  loop

…  body of the  loop

end  loop ;

k  : =  i ;

And on Kotlin:

val  i  =  100 ;

for  ( i  in  0 .. 9 ) {

…  loop body  } val k = i ;

Externally similar to the above loop in Pascal, it is interpreted unambiguously: the variable k will be assigned the value 100, since the variable i used outside this loop has nothing to do with the counter i , which is created and changed inside the loop… Such isolation of the counter is convenient and safe: no separate description is required for it and the probability of random errors associated with accidental destruction of variables external to the Loop is minimal. If a programmer needs to include a loop with a counter in the finished code, he may not check whether a variable exists with the name that he has chosen as a counter, he may not add a description of a new counter to the header of the corresponding procedure, he may not try to use one of the existing ones, but in this moment of “free” counters. He simply writes a loop with a counter variable, the name of which is convenient for him, and can be sure that no name collision will occur.

A Loop with a counter can always be written as a conditional Loop, before the start of which the counter is assigned an initial value, and the exit condition is when the counter reaches its final value; in this case, an operator for changing the counter by a given step is added to the body of the Loop. However, special operators of a loop with a counter can be translated more efficiently, since the formalized form of such a loop allows the use of special processor instructions for organizing loops.

Niklaus Wirth once called a loop with a counter “marginal”, arguing that such a construction is superfluous and should be excluded from the syntax of programming languages ​​as non-systemic. In accordance with this representation, there was no Loop with a counter in the Oberon programming language . However, in the language Oberon-2 , created by Wirth and Mössenbock in the development of Oberon, the loop with a counter FOR reappeared in the interests of practical usability .

In some languages, for example, C and others descended from it, a loop for, despite the syntactic form of a loop with a counter, is actually a loop with a precondition. That is, in C, the loop construct is:

for ( i = 0 ; i < 10 ; ++ i )
{
… the body of the loop

}

in fact, it is a different form of recording the construction [2] :

i = 0 ;
while ( i < 10 )
{
… the body of the loop ++ i ;
}

That is, in the construction, for first, an arbitrary statement of initialization of the loop is written, then – the continuation condition and, finally, some operation performed after each body of the loop (this does not have to be a change in the counter; it can be a pointer edit or some completely extraneous operation). For languages ​​of this kind, the problem described above can be solved very simply: the counter variable behaves in a completely predictable manner and after the end of the loop it retains its last value.

Joint Loop

Another version of the loop is a loop that specifies the execution of some operation for objects from a given set, without explicitly specifying the order in which these objects are enumerated. Such Loops are called joint (and Loops of collection , viewing Loops) and represent a formal notation of an instruction of the form: “Perform operation X for all elements included in the set M”. The joint loop, in theory, does not in any way determine in what order the operation will be applied to the elements of a set, although specific programming languages, of course, can specify a specific order of iterating over the elements. Arbitrariness makes it possible to optimize the execution of the Loop by organizing access not in a given programmer, but in the most advantageous order. If there is a possibility of parallel execution of several operations, it is even possible to parallelize the execution of a joint loop, when the same operation is simultaneously performed on different computational modules for different objects, while the program remains logically sequential.

Joint loops are available in some programming languages ​​( C  , Eiffel , Java , JavaScript , Perl , Python , PHP , LISP ,  Tcl , etc.) – they allow you to loop through all the elements of a given collection of objects . In the definition of such a loop, you only need to specify a collection of objects and a variable to which in the body of the loop will be assigned the value of the currently processed object (or a reference to it). The syntax of the operator is different in different programming languages:

Loop for C ++ :

for ( type & item : set ) // supported since the C ++ 11 standard {
// using item
}

Loop for C # :

foreach  ( type  item  in  set )
{
// using item
}

Loop for Delphi :

for  item  in  [ 1 .. 100 ]  do
begin
// Using item (Code performance was tested in Delphi 2010)
end ;

Loop for Perl (strict first-to-last order):

foreach  ( @set )
{
# use $ _
}

# or
for  ( @set )
{
# use $ _
}
# or
foreach  $ item  ( @set )
{
# use $ item
}

Loop for Eiffel :

across  set  as  cursor  loop
– using cursor.item
end

Loop for Java :

for  ( type  item  :  set )
{
// using item
}

JavaScript :

for  ( txtProperty  in  objObject )
{
/ *
usage:
objObject [txtProperty]
* /
}

Loop for PHP :

foreach  ( $ arr  as  $ item )  {
/ * use $ item * /
}
// or
foreach  ( $ arr  as  $ key => $ value )  {
/ * use the values ​​of the $ key index and its value $ value * /
}

Loop For Visual Basic . NET :

For  Each  item  As  type  In  set
‘using item
Next  item

Loop for Windows PowerShell :

foreach ($ item in $ set) {
# operations with $ item
}
Or
$ set | ForEach-Object {
# operations with $ _
}

Loop for Python

for  item  in  iterator_instance :
# using item

Loop for Ruby 

iterator_instance . each  do  | item |
# using item
end
Exit early and skip iteration

Many programming languages ​​that have cyclic constructions in their syntax also have specific commands that allow you to break the order of operation of these constructions: the command to exit the loop early and the command to skip iteration.

 Early exit from the Loop

 An early exit command is used when it is necessary to interrupt the execution of a Loop in which the exit condition has not yet been reached. This happens, for example, when an error is detected during the execution of the loop body, after which further work of the loop is meaningless.

An early exit command is usually called EXIT or break, and its action is similar to the action of an unconditional jump command (goto) on the command immediately following the Loop within which this command is located. So, in the C language, the two loops below work exactly the same:

// Application of the operator break
while ( < condition > )  {
…  statements
if  ( < error > )  break ;
…  statements
}
…  continuation of the  program

// A similar fragment  without break
while ( < condition > )  {
…  statements
if  ( < error > )  goto  break_label ;
…  statements
}
break_label :
…  continuation of the  program

In both cases, if the <error> condition is fulfilled in the body of the loop, the transition to the statements designated as “program continuation” will be made. Thus, the operator of early exit from the loop, in fact, simply masks an unconditional jump, however, using break is preferable to using goto, since the behavior of break is clearly defined by the language and is potentially less dangerous (there is, for example, no possibility of making a mistake with the position or name of the label). In addition, explicitly breaking out of the loop early does not violate structured programming principles.

The usual operator of an early exit interrupts the work of the Loop in which it is directly located. In a number of programming languages, the functionality of this operator has been extended, it allows you to exit from several nested loops (see below). In such cases, the Loop from which you want to exit is marked with a mark, and this mark is indicated in the early exit statement.

 Skip operation in Loop 

This operator is used when in the current loop iteration it is necessary to skip all commands to the end of the loop body. In this case, the loop itself should not be interrupted, the conditions for continuation or exit should be calculated in the usual way.

In C and its descendant languages, an operator continue in a loop construct is used as a command to skip iteration . The action of this operator is similar to the unconditional jump to the line within the loop body following its last command. For example, C code that finds the sum of the elements in an array and the sum of all positive elements in an array might look like this:

int arr [ ARRSIZE ];

// Summing separately all and only positive
// elements of the arr array using continue.
int sum_all = 0 ;
int sum_pos = 0 ;
for ( int i = 0 ; i < ARRSIZE ; ++ i )
{
sum_all + = arr [ i ];
if ( arr [ i ] <= 0 ) continue ;
sum_pos + = arr [ i ];
}

// Similar code with goto
int sum_all = 0 ;
int sum_pos = 0 ;
for ( int i = 0 ; i < ARRSIZE ; ++ i )
{
sum_all + = arr [ i ];
if ( arr [ i ] <= 0 ) goto cont_label ;
sum_pos + = arr [ i ];
cont_label :
}

The second fragment clearly shows how it works continue: it simply transfers control for the last command of the loop body, skipping the execution of the sum command if the next element of the array does not satisfy the condition. Thus, only the sum of the positive elements of the array is accumulated in sum_pos.

Requirement of Loop

From the point of view of structured programming, the commands to exit the loop early and continue iteration are redundant, since their action can be easily modeled by purely structural means. Moreover, according to a number of programming theorists (in particular, Edsger Dijkstra), the very fact of using non-structural means in a program, whether it be a classical unconditional jump or any of its specialized forms, such as break or continue, is evidence of an insufficiently developed algorithm for solving the problem.

However, in practice, the program code is often a record of an already existing, previously formulated algorithm, which is impractical to re Loop for purely technical reasons. An attempt to replace the early exit command with structural constructs in such code often turns out to be ineffective or cumbersome. For example, the above code snippet with a command break can be written like this:

// Early exit from the loop without break
bool flag = false ; // early termination flag while ( < condition > && ! flag ) {
… operators
if ( < error > ) {
flag = true ;
} else {
… operators
}
}
… continuation of the program

It is easy to make sure that the fragment will work similarly to the previous ones, the only difference is that at the place of checking for an error, instead of immediately exiting the loop, an early exit flag is set, which is checked later in the standard condition for continuing the loop. However, in order to refuse the early exit command, we had to add a flag description and a second branch of the conditional statement to the program; moreover, the program logic was “blurred” (the decision to exit early was made in one place, and executed in another). As a result, the program is neither simpler, nor shorter, nor clearer.

The situation is somewhat different with the skip iteration command. It is usually very easy and natural to replace it with a conditional operator. For example, the above fragment of summing an array can be written like this:

int arr [ ARRSIZE ];

// Summing separately all and only positive
// elements of the arr array with replacement continue
int sum_all = 0 ;
int sum_pos = 0 ;
for ( int i = 0 ; i < ARRSIZE ; ++ i )
{
sum_all + = arr [ i ];
if ( arr [ i ] > 0 ) // Condition changed to the opposite!
{
sum_pos + = arr [ i ];
}
}

As you can see, it was enough to replace the checked condition with the opposite one and place the final part of the loop body in a conditional statement. You can see that the program has become shorter (due to the removal of the skip iteration command) and at the same time more logical (from the code you can see directly that positive elements are summed up).

In addition, the use of the skip iteration command in a loop with a condition (while-loop) can also provoke an unobvious error: if the loop body, as is often the case, ends with commands to change the loop variable (s), then the skip iteration command will skip these commands too. as a result of which (depending on the condition under which the skip occurs) a loop or iteration repetition that does not correspond to the algorithm may occur. So, if you replace the for loop with while in the above example, you get the following:

int arr [ ARRSIZE ];

int sum_all = 0 ;
int sum_pos = 0 ;
int i = 0 ;

while ( i < ARRSIZE ) // The loop is outwardly similar to the previous one for … {
sum_all + = arr [ i ];
if ( arr [ i ] <= 0 ) continue ;
sum_pos + = arr [ i ];
++ i ; // … but this command will be skipped during continue execution // and the program will loop }

Despite their limited usefulness and the possibility of replacing them with other language constructs, the commands to skip iteration and, especially, to exit the loop early in some cases, are extremely useful, which is why they remain in modern programming languages.

Nested loops

It is possible to organize a loop inside the body of another loop. Such a loop will be called a nested loop . A nested loop in relation to a loop in the body of which it is nested will be called an inner loop , and vice versa, a loop in the body of which a nested loop exists will be called external in relation to a nested one. Inside the nested loop, in turn, another loop can be nested, forming the next nesting level, and so on. The number of nesting levels, as a rule, is not limited.

The total number of executions of the inner loop body does not exceed the product of the number of iterations of the inner and all outer loops. For example, taking three nested loops, each with 10 iterations, we get 10 executions of the body for the outer loop, 100 for the second-level loop, and 1000 in the innermost loop.

One of the problems associated with nested loops is organizing an early exit from them. In many programming languages is the operator of an early completion of the Loop ( break in C, exit Turbo Pascal, last in Perl , and so on. P.), But it usually provides the only way out of the Loop of the level, where called. Calling it from a nested loop will terminate only this inner loop, while the outer loop will continue to execute. The problem may seem contrived, but it does sometimes arise when programming complex data processing, when the algorithm requires an immediate interruption under certain conditions, the presence of which can only be checked in a deeply nested loop.

There are several solutions to the problem of exiting nested loops.

  • The simplest is to use the goto operator to exit to the point in the program immediately following the nested loop. This option is criticized by supporters of structured programming , as well as all constructs that require the use of goto. Some programming languages, for example, Modula-2 , simply do not have an unconditional jump operator, and such a construction is impossible in them.
  • An alternative is to use the standard means of completing Loops, if necessary, setting special flags that require immediate completion of processing. The disadvantage is the complication of the code, the decrease in performance.
  • Placing a nested loop in a procedure. The idea is that all action that may need to be interrupted early should be formalized as a separate procedure, and for early termination, use the procedure exit operator (if there is one in the programming language). In the C language, for example, you can build a function with a nested loop, and exit from it using the return statement. The disadvantage is that the allocation of a code fragment into a procedure is not always logically justified, and not all languages ​​have standard means of early completion of procedures.
  • Take advantage of the mechanism for throwing and handling exceptions(exceptions), which is now available in most high-level languages . In this case, in an abnormal situation, the code in the nested loop raises an exception, and the exception handling block, which contains the entire nested loop, intercepts and processes it. The disadvantage is that the implementation of the exception handling mechanism in most cases is such that the speed of the program is reduced. True, in modern conditions this is not particularly important: in practice, the loss of performance is so small that it matters only for very few applications.
  • Finally, there are language-specific tools for breaking out of nested loops. So, in the Ada language, a programmer can mark a loop (the top level of a nested loop) with a label, and specify this label in the command for early termination of the loop. The exit will take place not from the current loop, but from all nested loops up to the marked one, inclusive . The PHP language provides the ability to specify the number of interrupted loops after the command break – this is how the break 2loop itself and the one above it will interrupt, and it is break 1equivalent to a simple command record break.

Loops with multiple guarded branches

 Dijkstra Loop

In programming theory, there is another, fundamentally different from the “classical” form of a cyclic construction, called “Dijkstra’s Loop”, named after Edsger Dijkstra , who first described it. In the classical Dijkstra description, such a Loop looks like this:

do
P 1 → S 1 ,

P n → S n
do

Here do is the marker of the beginning of the loop construction, od is the marker of the end of the loop construction, P i  is the i -th guarding condition (a logical expression that can have the value “true” or “false”), S i  is the i -th guarded command . The Loop consists of one or more branches ( guarded expressions ), each of which is a pair of guarded condition (or, in short, “guards”) and guarded command (understandably, the command can be complex in reality).

When the Dijkstra Loop is executed, the guard conditions are calculated in each iteration. If at least one of them is true, the corresponding guarded command is executed, after which a new iteration begins (if several guard conditions are true, only one guarded command is executed). If all guard conditions are false, the Loop ends. It is easy to see that Dijkstra’s Loop with one guarding condition and one guarded command is, in fact, an ordinary Loop with a precondition (the “bye” Loop).

Although the Dijkstra Loop was invented back in the 1970s, programming languages ​​do not contain special constructs for creating it. The only exception was the recently created Oberon-07  , the first real programming language to explicitly support a loop with multiple guarded branches. However, Dijkstra’s loop can be modeled without much difficulty using traditional structures of structural programming languages. Here is an example of its implementation in one of the possible ways in the language of Ada:

loop
if  P1  then
S1 ;

elsif  Pn  then
Sn ;
else
exit ;
end  if ;
end  loop ;

Here P1 — Pn are guard conditions and S1 — Sn are the corresponding guarded commands. Dijkstra’s loop is useful for some specific repetitive computations that are awkward to describe using more traditional looping constructs. For example, this Loop naturally represents a finite automaton  – each branch corresponds to one state of the automaton, the protected conditions are constructed so that in the current iteration the branch corresponding to the current state of the automaton is selected, and the code of the protected command ensures that computations are performed in the current state and transition to the next one (i.e. such a change in variables, after which the guarding condition of the desired branch will be true at the next iteration).

Spider Loop

It is easy to see that Dijkstra’s Loop does not contain an explicit continuation or exit condition, which is not considered a blessing by all programming theorists. Therefore, a complicated construction of the Dijkstra Loop was proposed, called the “spider-Loop”. In the same notation, it looks like this:

do
P 1 → S 1 ,

P n → S n
out
Q 1 → T 1 ,

Q n → T n
else
E
do

Here, after the marker out, completion branches are added , consisting of exit conditions Q i and completion commands T i . In addition, an alternate completion branch else with the E command has been added .

The spider loop runs like this:

  • Safeguarding conditions are calculated. If a true guard condition exists, the corresponding guarded command is executed.
  • The exit conditions are calculated. If a true exit condition exists, the corresponding exit command is executed, and then the loop ends. If all exit conditions are false, the next iteration begins, but only if at least one of the guard conditions was true in the current iteration.
  • If in this iteration all guard conditions and all exit conditions turned out to be false, an alternative termination command E is executed, after which the execution of the loop is interrupted.

The structure of the ‘spider’ Loop allows you to very strictly describe the conditions for the execution of the Loop. According to the theoretical provisions, the alternative termination branch should not be used as one of the options for the correct termination of the Loop (all such options should be formalized in the form of the corresponding termination branches with an explicit condition), it only serves to track the situation when for some then for reasons the Loop began to run abnormally. That is, the alternate completion command can only analyze the causes of the error and present the analysis results.

Although there is no explicit syntax support for this loop in any programming language, the spider loop, like Dijkstra’s loop, can be modeled using traditional structural constructs.

VLOOKUP Graduation CourseSarkari YojanaIndia Top ExamExcel Tutorial
Spread the love

Leave a Comment