Team LiB   Previous Section   Next Section

4.6 Control Statements

Control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed. (see Chapter 2 for a discussion of automatic and other object lifetimes)

C++ supports the following control statements:

break;

A break statement can be used only in the body of a loop or switch statement. It terminates the loop or switch statement and transfers execution to the statement immediately following the loop or switch.

In a nested loop or switch, the break applies only to the innermost statement. To break out of multiple loops and switches, you must use a goto statement or redesign the block to avoid nested loops and switches (by factoring the inner statement into a separate function, for example). Example 4-7 shows a simple use of break.

Example 4-7. Using break to exit a loop
// One way to implement the find_if standard algorithm.
template<typename InIter, typename Predicate>
InIter find_if(InIter first, InIter last, Predicate pred)
{
  for ( ; first != last; ++first)
    if (pred(*first))
      break;

  return first;
}
continue;

A continue statement can be used only in the body of a loop. It causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating (if the condition is true). In a for loop, the iterate-expr is evaluated before testing the condition. Example 4-8 shows how continue is used in a loop.

Example 4-8. Using continue in a loop
#include <cmath>
#include <iostream>
#include <istream>
#include <limits>
#include <ostream>

int main(  )
{
  using std::cin;
  using std::cout;
  while(true) {
    cout << "Enter a number: ";
    double x;
    cin >> x;
    if (cin.eof(  ) || cin.bad(  ))
      // Input error: exit
      break;
    else if (cin.fail(  )) {
      // Invalid input: skip the rest of the line
      cin.clear(  );
      cin.ignore(std::numeric_limits<int>::max(  ), '\n');
       continue; 
    }
    cout << "sqrt(" << x << ")=" << std::sqrt(x) << std::endl;
  }
}
goto identifier ;

The goto statement transfers control to the statement that has identifier as a label. The goto statement and the labeled statement must be in the same function. Jumping into a block is usually a bad idea. In particular, if the jump bypasses the declaration of an object, the results are undefined unless the object has POD type and no initializer. (See Chapter 2 for information about POD types and initializers.) Example 4-9 shows some uses of goto statements.

Example 4-9. goto statements
#include <iostream>
#include <ostream>

int main(int argc, char* argv[])
{
  int matrix[4][5];
  for (int i = 0; i < 4; ++i)
    for (int j = 0; j < 5; ++j)
      if (! (std::cin >> matrix[i][j]))
         goto error; 
   goto end; 

 error: 
  std::cerr << "Need 20 values for the matrix\n";
 end: 
  return 0;
}
return ;
return expr ;

The return statement transfers execution out of a function to the caller. The first form does not return a value, so it should be used only in functions of type void, in constructors, and in destructors. The latter form cannot be used in constructors and destructors. In a function of type void, you can use the second form, but only if expr has type void. See Chapter 5 for more information about returning from functions.

figs/acorn.gif

The value of expr is converted to the function's return type and returned to the caller. The compiler is free to construct a temporary object and copy expr when returning. Some compilers optimize away the extra copy.

If execution reaches the last statement of a function without executing a return statement, an implicit return; is assumed. If the function has a non-void return type, the behavior is undefined.

The main function is special. If it ends without a return statement, return 0; is assumed.

identifier : statement

Any statement can have a label. A label is used only as a target of a goto statement. Label identifiers must be unique within a function; the scope of a label is the function in which it is declared. Label identifiers do not conflict with any other identifiers.

A statement can have multiple labels, including case and default labels.

    Team LiB   Previous Section   Next Section