C++ Intro

Lecture: C++ flow control


if...else statement

The if-else statement is needed to express decisions. Formally the syntax is

   if ( condition ) {
        // do something if condition evaluates to true
        // ...
    } else {
        // otherwise do something else
        // ...
    }
  • else part is optional;
  • when result of condition is true, the body of the else statement is never executed;
  • when result of condition is false, the body of the if statement is never executed;
  • the condition is true if a logical expression evaluates to true, or if a numeric expression evaluates to non-zero.

else if construct

Consider construct

   if ( condition1 )
       statement
       
   else if ( condition2 )
       statement
       
   else if ( condition3 )
       statement
       
   else if ( condition4 )
       statement
       
   else
       statement

This is the most general way of writing a multi-way decision:

  • each condition is evaluated in order;
  • if a condition is true, the statement associated with it is executed, and this terminates the whole if-else chain.
  • As always, the code for each statement is either a single statement, or a group of statements in braces { }.
  • The last else part handles the "none of the above" or some sort of default case, where none of the other conditions is satisfied.
  • Sometimes there is no explicit action for the default; in that case the trailing
       else
           statement
    can be dropped, or it may be used for error checking to catch an "impossible" condition.

while loop

Few programs are written without loops. The while statement executes until its condition becomes false. That is, the condition in parentheses is tested. If it is true , the body of the loop, made up by the statements enclosed in braces { ... } is executed. Then the condition is re-tested, and if true, the body is executed again. When the test becomes false, the loop ends, and execution continues at the statement that follows the loop:

    while ( i < j ) {
        i = 2 * i;
    }
                    

for loop

The for statement is another kind of a C++ loop construct. It is preferable when there is variable with a simple initialization, a condition to test, and an increment. The for loop keeps these three loop-control statements close together and visible at the top of the loop. This is most obvious in

   for ( int x = 0; x < 5; ++x ) {
        std::cout << x;
    }

The above for statement is interpreted step-by step as follows:

  1. Set x to zero.
  2. If x is less than 5, execute the body of the loop, that is, send the value of x to the standard output.
  3. Increment x. When applied to an integer variable, the increment operator ++ simply adds 1 to x .
  4. Repeat step 2. If condition ( x < 5 ) no longer true, loop terminates, that is, next statement after the closing brace is executed next.

switch statement

A switch statement tests a value against a set of constants specified by a list of case labels. The case constants must be distinct, and if the value tested does not match any of them, the default is chosen. The programmer need not provide a default.

    std::cout << "Do you want to proceed (y or n)?\n"; // display question
    char answer = 0;
    std::cin >> answer; // read answer
    switch ( answer ) {
        case 'y':
            return true;
        case 'n':
            return false;
        default:
            std::cout << "Sorry, I don't understand\n";
            std::cout << "I'll take that for a no\n";
            return false;
    }

If a case matches the expression value, execution starts at that case. All case expressions must be different. The case labeled default is executed if none of the other cases are satisfied. A default is optional; if it isn't there and if none of the cases match, no action at all takes place. Cases and the default clause can occur in any order.

The break statement causes an immediate exit from the switch:

    bool proceed = false ;
    std::cout << "Do you want to proceed (y or n)? "; // display question
    char answer = 0;
    std::cin >> answer; // read answer
    switch ( answer ) {
        case 'Y':
        case 'y':
            proceed = true;
            break;
        default:
            std::cout << "Sorry, I don't understand\n";
            std::cout << "I'll take that for a no\n";
        case 'N':
        case 'n':
            proceed = false;
            break;
    }

Because cases are simple labels, after the code for one case is done, execution falls through to the next unless you take explicit action to escape. Most common ways to leave a switch are break and return statements. A break statement can also be used to force an immediate exit from while and for loops.

Falling through cases is a mixed blessing. On the positive side, it allows several cases to be attached to a single action, as with the combinations of character literals ( 'Y', 'y') and (default, 'N', 'n') in the last example. But it also implies that normally each case must end with a break to prevent falling through to the next. Falling through from one case to another is not robust, being prone to disintegration when the program is modified. With the exception of multiple labels for a single computation, fall-throughs should be used sparingly, and well commented.

As a matter of good form, put a break after the last case, including default, even though the break from the last case isn't logically necessary. Some day when another case gets added at the end, this bit of defensive programming will save you.