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
.
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.
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.