Control Flow

------------Overview of Control Flow Statements-----------

    Control flow statements govern the flow of control in a program during execution, that is, the
order in which statements are executed in a running program. There are three main categories of
control flow statements that are discussed in this chapter:
• Selection statements: if, if-else and switch.
• Iteration statements: while, do-while and for.
• Transfer statements: break, continue, return, try-catch-finally and assert.

 

 

 Selection Statements-

   Java provides selection statements that allow the program to choose between alternative actions
during execution. The choice is based on criteria specified in the selection statement. These
selection statements are
• simple if Statement
• if-else Statement
• switch Statement

 

 

Simple if Statement

The simple if statement has the following syntax: if (<conditional expression>)
    <statement>
It is used to decide whether an action is to be performed or not, based on a condition. The
condition is specified by <conditional expression> and the action to be performed is specified by
<statement>.
The semantics of the simple if statement are straightforward. The <conditional expression> is
evaluated first. If its value is true, then <statement> (called the if block) is executed and execution
continues with the rest of the program. If the value is false, then the if block is skipped and
execution continues with the rest of the program.

     In the following examples of the if statement, it is assumed that the variables and the methods
have been defined appropriately:


if (emergency) // emergency is a boolean variable
operate();
if (temperature > critical)
soundAlarm();
if (isLeapYear() && endOfCentury())
celebrate();
if (catIsAway()) { // Block
getFishingRod();
goFishing();
}


Note that <statement> can be a block, and the block notation is necessry if more that one
statement is to be executed when the <conditional expression> is true.
Since the <conditional expression> must be a boolean expression, it avoids a common
programming error: using an expression of the form (a=b) as the condition, where inadvertently
an assignment operator is used instead of a relational operator. The compiler will flag this as an
error, unless both a and b are boolean.
Note that the if block can be any valid statement. In particular, it can be the empty statement (;) or
the empty block ({}). A common programming error is an inadvertent use of the empty statement.
if (emergency); // Empty if block
operate(); // Executed regardless of whether it was an emergency or not.

 

 

if-else Statement

The if-else statement has the following syntax: if(<conditional expression>)
<statement1>
else
<statement2>
It is used to decide between two actions, based on a condition.
The <conditional expression> is evaluated first. If its value is true, then <statement1> (the if
block) is executed and execution continues with the rest of the program. If the value is false, then
<statement2> (the else block) is executed and execution continues with the rest of the program. In
other words, one of two mutually exclusive actions is performed. The else clause is optional; if
omitted, the construct reduces to the simple if statement.
In the following examples of the if-else statement, it is assumed that all variables and methods
have been defined appropriately:


if (emergency)
operate();
else
joinQueue();
if (temperature > critical)
soundAlarm();
else
businessAsUsual();
if (catIsAway()) {
getFishingRod();
goFishing();
} else
playWithCat();
Since actions can be arbitrary statements, the if statements can be nested.
if (temperature >= upperLimit) { // (1)
if (danger) // (2) Simple if.
soundAlarm();
if (critical) // (3)
evacuate();
else // Goes with if at (3).
turnHeaterOff();
} else // Goes with if at (1).
turnHeaterOn();


The use of the block notation, {}, can be critical to the execution of if statements. The if
statements (A) and (B) in the following examples do not have the same meaning.
The if statements (B) and (C) are the same, with extra indentation used in (C) to make the
meaning evident. Leaving out the block notation in this case could have catastrophic
consequences: the heater could be turned on when the temperature is above the upper limit.

// (A)
if (temperature > upperLimit) { // (1) Block notation.
if (danger) soundAlarm(); // (2)
} else // Goes with if at (1).
turnHeaterOn();
// (B)
if (temperature > upperLimit) // (1) Without block notation.
if (danger) soundAlarm(); // (2)
else turnHeaterOn(); // Goes with if at (2).
// (C)
if (temperature > upperLimit) // (1)
if (danger) // (2)
soundAlarm();
else // Goes with if at (2).
turnHeaterOn();


The rule for matching an else clause is that an else clause always refers to the nearest if that is not
already associated with another else clause. Block notation and proper indentation can be used to
make the meaning obvious.
   Cascading if-else statements are a sequence of nested if-else statements where the if of the next ifelse statement is joined to the else clause of the previous one. The decision to execute a block is
then based on all the conditions evaluated so far.
    if (temperature >= upperLimit) { // (1)
soundAlarm();
turnHeaterOff();
} else if (temperature < lowerLimit) { // (2)
soundAlarm();
turnHeaterOn();
} else if (temperature == (upperLimit-lowerLimit)/2) { // (3)
doingFine();
} else // (4)
noCauseToWorry();

The block corresponding to the first if condition that evaluates to true is executed, and the
remaining ifs are skipped. In the example given above, the block at (3) will execute only if the
conditions at (1) and (2) are false and the condition at (3) is true. If none of the conditions are
true, the block associated with the last else clause is executed. If there is no last else clause, no
actions are performed.

 

 

switch Statement

Conceptually the switch statement can be used to choose one among many alternative actions,
based on the value of an expression. Its general form is as follows:
switch(<non-long integral expression>){
case label1: <statement1>
case label2: <statement2>
...
case labeln: <statementn>
default: <statement>
} // end switch
The syntax of the switch statement comprises a switch expression followed by the switch body,
which is a block of statements. The type of the switch expression is non-long integral (i.e., char,
byte, short, or int). The statements in the switch body can be labeled, defining entry points in the
switch body where control can be transferred depending on the value of the switch expression.
The semantics of the switch statement are as follows:
• The switch expression is evaluated first.
• The value of the switch expression is compared with the case labels. Control is transferred to the
<statementi> associated with the case label that is equal to the value of the switch expression.
After execution of the associated statement, control falls through to the next statement unless
appropriate action is taken.
• If no case label is equal to the value of the switch expression, the statement associated with the
default label is executed.

 

 

Example 1 Fall Through in switch Statement


public class Advice {
public final static int LITTLE_ADVICE = 0;
public final static int MORE_ADVICE = 1;
public final static int LOTS_OF_ADVICE = 2;
public static void main(String[] args) {
dispenseAdvice(LOTS_OF_ADVICE); }
public static void dispenseAdvice(int howMuchAdvice) {
switch(howMuchAdvice) {
case LOTS_OF_ADVICE:
System.out.println("See no evil."); // (2)
case MORE_ADVICE:
System.out.println("Speak no evil."); // (3)
case LITTLE_ADVICE:
System.out.println("Hear no evil."); // (4) break; //(5)
 default:
System.out.println("No advice."); // (6) }
}
}

Output from the program:

See no evil.
Speak no evil.
Hear no evil.

 

 

Example 2 Using break in switch Statement

public class Digits {
public static void main(String[] args) {
System.out.println(digitToString('7') + " " + digitToString('8') + " " +
digitToString('6'));
}
public static String digitToString(char digit) { String str = "";
switch(digit) {
case '1': str = "one";
 break;
case '2': str = "two";
 break;
case '3': str = "three";
 break;
case '4': str = "four";
 break;
case '5': str = "five";
 break;
case '6': str = "six"; 
break;
case '7': str = "seven";
 break;
case '8': str = "eight";
 break;
case '9': str = "nine";
 break;
case '0': str = "zero";
 break;
default: System.out.println(digit + " is not a digit!"); }
return str;
}
}

Output from the program:

seven eight six

 

 

Example 3 Nested switch Statement

public class Seasons {
public static void main(String[] args) {
int monthNumber = 11;
switch(monthNumber) { // (1) Outer
case 12: case 1: case 2:
System.out.println("Snow in the winter.");
break;
case 3: case 4: case 5:
System.out.println("Green grass in spring.");
break;
case 6: case 7: case 8:
System.out.println("Sunshine in the summer.");
break;
case 9: case 10: case 11: // (2)
switch(monthNumber) { // Nested switch (3) Inner
case 10:
System.out.println("Halloween.");
break;
case 11:
System.out.println("Thanksgiving.");
break;
} // end nested switch
// Always printed for case labels 9, 10, 11
System.out.println("Yellow leaves in the fall."); // (4)
break;
default:
System.out.println(monthNumber + " is not a valid month."); }
}
}

Output from the program:

Thanksgiving.
Yellow leaves in the fall.

 

 

---------------------Iteration Statements----------------------------

Loops allow a block of statements to be executed repeatedly (i.e., iterated). A boolean condition
(called the loop condition) is commonly used to determine when to terminate the loop. The
statements executed in the loop constitute the loop body. The loop body can be a single statement
or a block. Java provides three language constructs for constructing loops:
• while statement
• do-while statement
• for statement

 

 

while Statement

The syntax of the while loop is

while (<loop condition>)
<loop body>

The loop condition is evaluated before executing the loop body. The while statement executes the
loop body as long as the loop condition is true. When the loop condition becomes false, the loop
is terminated and execution continues with the statement immediately following the loop. If the
loop condition is false to begin with, the loop body is not executed at all. In other words, a while
loop can execute zero or more times.

The while statement is normally used when the number of iterations is not known a priori.
while (noSignOfLife())
keepLooking();

Since the loop body can be any valid statement, inadvertently terminating each line with the
empty statement (;) can give unintended results.

while (noSignOfLife()); // Empty statement as loop body!
keepLooking(); // Statement not in the loop body

 

 

do-while Statement

The syntax of the do-while loop is

do
<loop body>
while (<loop condition>);

  The loop condition is evaluated after executing the loop body. The do-while statement executes
the loop body until the loop condition becomes false. When the loop condition becomes false, the
loop is terminated and execution continues with the statement immediately following the loop.
Note that the loop body is executed at least once.

   The loop body in a do-while loop is invariably a statement block. It is instructive to compare the
while and the do-while loops. In the examples below, the mice might never get to play if the cat is
not away, as in the loop at (1). The mice do get to play at least once (at the peril of losing their
life) in the loop at (2).
while (cat.isAway()) { // (1)
mice.play();
}
do { // (2)
mice.play();
while (cat.isAway());

 

 

for Statement

The for loop is the most general of all the loops. It is mostly used for counter-controlled loops,
that is, when the number of iterations is known beforehand.
The syntax of the loop is as follows:
for (<initialization>; <loop condition>; <increment expression>)
<loop body>
The <initialization> usually declares and initializes a loop variable that controls the execution of
the <loop body>. The <loop condition> is a boolean expression, usually involving the loop
variable, such that if the loop condition is true, the loop body is executed; otherwise, execution
continues with the statement following the for loop.
After each iteration (i.e., execution of the loop body), the <increment expression> is executed.
This usually modifies the value of the loop variable to ensure eventual loop termination. 
The loop condition is then tested to determine if the loop body should be executed again. Note that the  <initialization> is only executed once on entry to the loop.

 

 

 

--------------------Transfer Statements------------------------------

Java provides six language constructs for transferring control in a program:
• break
• continue
• return
• try-catch-finally
• throw
• assert
This section discusses the first three statements, and the remaining statements are discussed in
subsequent sections.
Note that Java does not have a goto statement, although goto is a reserved word.

 

 

Labeled Statements

A statement may have a label.

<label> : <statement>

A label is any valid identifier and it always immediately proceeds the statement. Label names
exist in their own name space, so that they do not conflict with names of packages, classes,
interfaces, methods, fields, and local variables. The scope of a label is the statement prefixed by
the label, meaning that it cannot be redeclared as a label inside the labeled statement—analogous
to the scope of local variables.


L1: if (i > 0) {
L1: System.out.println(i); // (1) Not OK. Label redeclared. }
L1: while (i < 0) { // (2) OK.
L2: System.out.println(i);
}
L1: { // (3) OK. Labeled block. int j = 10;
System.out.println(j);
}
L1: try { // (4) OK. Labeled try-catch-finally block.
int j = 10, k = 0;
L2: System.out.println(j/k);
} catch (ArithmeticException ae) {
L3: ae.printStackTrace();
} finally {
L4: System.out.println("Finally done.");
}

A statement can have multiple labels:
 LabelA: LabelB: System.out.println("Mutliple labels. Use judiciously.");
A declaration statement cannot have a label:
L0: int i = 0; // Compile time error.
    A labeled statement is executed like it was non-labeled, unless it contains the break or continue
statements. This is discussed in the next two subsections.

 

 

break Statement

The break statement comes in two forms: the unlabeled and the labeled form.
break; // the unlabeled form
break <label>; // the labeled form
 
The unlabeled break statement terminates loops (for, while, do-while) and switch statements
which contain the break statement, and transfers control out of the current context (i.e., the closest
enclosing block).

 

 

Example 4 break Statement

class BreakOut
 {
public static void main(String[] args) 
  {
     for (int i = 1; i <= 5; ++i) {
     if (i == 4) break; // (1) Terminate loop. Control to (2).
    // Rest of loop body skipped when i gets the value 4.
    System.out.println(i + "\t" + Math.sqrt(i));
  } // end for
   // (2) Continue here.
   int n = 2;
   switch (n)
   {
     case 1: System.out.println(n); break;
     case 2: System.out.println("Inner for loop: ");
     for (int j = 0; j < n; j++)
     if (j == 2)
     break; // (3) Terminate loop. Control to (4).
    else
    System.out.println(j);
    default: System.out.println("default: " + n); // (4) Continue here. }
  }
}
Output from the program:
1 1.0
2 1.4142135623730951
3 1.7320508075688772
Inner for loop:
0
1
default: 2

 

 

Example 5 Labeled break Statement

class LabeledBreakOut 
{
   public static void main(String[] args)
    {
       int[][] squareMatrix = {{4, 3, 5}, {2, 1, 6}, {9, 7, 8}};
       int sum = 0;
       outer: // label
       for (int i = 0; i < squareMatrix.length; ++i){ // (1)
       for (int j = 0; j < squareMatrix[i].length; ++j) { // (2)
       if (j == i) break; // (3) Terminate this loop.
      // Control to (5).
       System.out.println("Element[" + i + ", " + j + "]: " +
       squareMatrix[i][j]);
       sum += squareMatrix[i][j];
       if (sum > 10) break outer;// (4) Terminate both loops. 95
      // Control to (6). } // end inner loop
      // (5) Continue with outer loop.
     } // end outer loop
     // (6) Continue here.
  System.out.println("sum: " + sum);
}
}
Output from the program:
Element[1, 0]: 2
Element[2, 0]: 9
sum: 11

 

 

continue Statement

Like the break statement, the continue statement also comes in two forms: the unlabeled and the
labeled form.

continue; // the unlabeled form
continue <label>; // the labeled form

Example 6 continue Statement
class Skip
 {
    public static void main(String[] args)
  {
    for (int i = 1; i <= 5; ++i)
   {
    if (i == 4) continue; // (1) Control to (2).
    // Rest of loop body skipped when i has the value 4.
    System.out.println(i + "\t" + Math.sqrt(i));
    // (2). Continue with increment expression.
    } // end for
  }
}
Output from the program:
1     1.0
2     1.4142135623730951
3     1.7320508075688772
5     2.23606797749979

 

 

Example 7 Labeled continue Statement

class LabeledSkip 
{
   public static void main(String[] args)
 {
    int[][] squareMatrix = {{4, 3, 5}, {2, 1, 6}, {9, 7, 8}};
    int sum = 0;
    outer: // label
    for (int i = 0; i < squareMatrix.length; ++i)
     { // (1)
        for (int j = 0; j < squareMatrix[i].length; ++j)
         { // (2)
            if (j == i) continue; // (3) Control to (5).
            System.out.println("Element[" + i + ", " + j + "]: " +
            squareMatrix[i][j]);
            sum += squareMatrix[i][j];
            if (sum > 10) continue outer; // (4) Control to (6).
            // (5) Continue with inner loop.
         } // end inner loop
         // (6) Continue with outer loop.
     } // end outer loop
  System.out.println("sum: " + sum);
 }
}
Output from the program:
Element[0, 1]: 3
Element[0, 2]: 5
Element[1, 0]: 2
Element[1, 2]: 6
Element[2, 0]: 9
sum: 25

 

 

return Statement

The return statement is used to stop execution of a method and transfer control back to the calling
code (a.k.a. the caller). The usage of the two forms of the return statement is dictated by whether
it is used in a void or a non-void method. The first form does not return any value to the calling
code, but the second form does. Note that the keyword void does not represent any type.

 

 

 Example 8 The return Statement

public class ReturnDemo
  {
      public static void main (String[] args) 
      { // (1) void method can use return.
         if (args.length == 0) return;
         output(checkValue(args.length));
        }
    static void output(int value) { // (2) void method need not use return.
    System.out.println(value);
    return 'a'; // Not OK. Cannot return a value.
}
static int checkValue(int i)
    { // (3) non-void method must return a value.
       if (i > 3)
       return i; // OK.
      else
       return 2.0; // Not OK. double not assignable to int.
   }
}

1 comment: