C H A P T E R  12

image

Loops and Flow Control

Control Statements

Control statements direct the program to perform a set of operations repeatedly until some condition exists that terminates the repetition. packetC provides all of the C control statements. This includes for-loops, while-do, do-while, and do-until, as well as jump controls such as goto, break, continue, return, and exit. There are no surprises with regard to how packetC implements these control statements.

Looping (Iteration) Statements

Do_while Statement
do  statement  while  (  expression  )  ;

This construct executes its statement, which can be a compound statement, then evaluates an associated expression. As long as the expression is evaluated as true, the statement is executed and the expression is reevaluated. The do-while statement always executes its associated statement at least once.

// Example
do {
   handleInstance();
   instanceCount++;
   instancesRemain = analyzeSituation();
} while ( instancesRemain );
While Statement
while  (  expression  )  statement

A while statement first evaluates its controlling expression. As long as the expression evaluates to true, the associated statement, which can be a compound statement, is executed.

while ( instancesRemain ) {
   handleInstance();
   instanceCount++;
   instancesRemain = analyzeSituation();
}
For Statement
for  ( expressionopt ; boolean_expression ; expressionopt )  statement
for  ( declarationopt ; boolean_expression ; expressionopt )  statement

A for statement consists of a control part and an associated statement, which can be a compound statement. The control part consists of a pre-loop component, a controlling expression, and a post-loop component. The pre-loop component is typically used to declare and initialize control variables; it consists either of a single optional declaration or an expression. The scope of a pre-loop declaration is the remainder of the control part and the associated statement. A pre-loop expression (assignment, variable increment or decrement) is evaluated as if it were being cast to void. The pre-loop component is executed once, before the control expression's initial evaluation.

The controlling expression is evaluated after the pre-loop component's execution and after each execution of the control part's associated statement. If the expression is evaluated as true, the associated statement(s) are executed and then the post-loop component is executed. If the controlling expression evaluates to false, execution of for statement components ceases. The post-loop component consists of an optional expression. Like a pre-loop expression, it is evaluated as if it were being cast to a void type; it is typically used to increment or decrement a variable.

The pre-loop and post-loop components can be omitted, although the semicolons on either side of the controlling expression must be present. Unlike C99, packetC does not allow the controlling expression to be omitted.

// Examples
for ( index = 0; index < 4; index++) {
   processArray ( arr[index] );
       …
}

//
for ( int j = 0; j < 4; j++) {
   processArray ( arr[j] );

}

Finally, fear the infinite loop!

Jump Statements

Within packetC, multiple varieties of jump statements exist that control the flow of application logic. These include break, continue, goto, return, and exit.

Break Statement

A break statement breaks the flow of control when it appears within an iterative statement or switch statement. It causes an immediate exit from whichever of the following packetC statements enclose it more immediately than any other: while, for, do…while, or switch.

while ( condition_holds ) {
          …
          switch (myVar) {
          case 0 : counter0++;
                   break;   // causes exit from switch, not exit from while
          case 1:  counter1++
                           …
   }  // end of switch statement structure
   a += myVar;
   ...
   break; // causes exit from while
}

A break statement can be utilized outside of a switch construct. However, it can make programs difficult to follow and there almost always are more intuitive methods to code a given form of the expression. As such, usage of break outside of switch is not suggested within packetC; however, it is legal.

Continue Statement

A continue statement affects the flow of control of the innermost iterative statement enclosing it by skipping the remaining statements within the body of that enclosing statement and proceeding with the next iteration. If a continue statement is executed from within such a while or do…while statement, the loop continuation test is executed next. A continue statement executed within a for-statement results in the post-loop statement being executed, then the continuation test is executed.

for ( j = 0; j < max; j++ ) {
             while ( condition_holds ) {
             …  // statement a

            // skip statement b, re-evaluate while loop continuation test
            if ( j == 3) continue;
            …  // statement b
         }
}
Goto Statement

A goto statement specifies that a jump is to be made to a statement with the specified label name. That statement must be within the function that encloses the goto statement; goto-driven jumps cannot be made into an enclosed function or into a scope outside the enclosing function. The goto statement's identifier is the label name, not a variable holding a string representation of the name or one holding an address value.

goto START_HERE; // ERROR cannot jump into an enclosed function

int  myFn (int j, int k)
{
    if ( k > 12 ) {
       goto START_HERE;  // legal jump within current scope
    }
    …
    START_HERE:
    …
   }

The effect of a goto statement is undefined when it jumps into code that programming logic would otherwise render unreachable (e.g., a loop with a condition that is known at compile time to always be false). Such a practice relies on compiler control flow and dead code elimination being done in a particular way. Since reliability is a principal goal of packetC, implementations are not required to support this programming technique.

if ( 5 > 12 ) {
   INSIDE_LOOP: counter++;
   goto AFTERWARD;
}
goto INSIDE_LOOP;  // Undefined event, since the conditional would otherwise never
                   // execute to INSIDE_LOOP AFTERWARD:

The goto statement is one of the most controversial in the world of C given that it has always seemed to be a throwback to earlier generations of languages and a hack if it's used.

In packetC, however, there are many sections of code that, when optimized, are most efficient when using goto. As such, when used within a constrained region of code without possibility of jumps to unforeseen sections of code, goto can be a formidable tool in the optimization for performance category that fits well with packetC.

That said; avoid the urge, just like macros, wherever possible.

Return Statement

A return statement returns control to a function's caller. If the function has a return type of void, the return statement shall not be associated with an expression. Otherwise, the statement shall be associated with an expression of the type returned by the function invocation. Each function shall contain a return statement.

int myFn1( int j, int k )
{
               return j * k + 5;  // return int
   }

void myFn2 ()
{
    …
    return;                       // return void
}
Exit Statement

An exit statement terminates processing of the packet and jumps to the end of main() without any further processing.

void myFunction ()
{
      …
   exit;   // Terminate Processing of Packet No Matter Where We Are In Code
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.81.43