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