A selection statement selects among a set of statements depending on
the value of a controlling expression. The selection statements are
the if
statement and the switch
statement,
which are discussed in the following sections.
The if
statement has the following syntax:
if ( expression ) statement
else(opt) else-statement(opt)
The statement following the control expression is executed
if the value of the control expression is true (nonzero). An
if
statement can be written with an optional
else
clause that is executed if the control expression
is false (0).
Consider the following example:
if (i < 1) funct(i); else { i = x++; funct(i); }
In this example, if the value of i
is less than 1, then
the statement funct(i)
is executed and the compound
statement following the keyword else
is not executed.
If the value of i
is not less than 1, then only the
compound statement following the keyword else
is
executed.
The control expression in a selection statement is usually a logical expression, but it can be any expression of scalar type.
When if
statements are nested, an else
clause matches the most recent if
statement that does
not have an else
clause, and is in the same block. For
example:
if (i < 1) { if (j < 1) funct(j); if (k < 1) /* This if statement is associated with */ funct(k); else /* this else clause. */ funct(j + k); }
The switch
statement executes one or more of a series
of cases, based on the value of a controlling expression. The
switch
statement has the following syntax:
switch ( expression ) statement
The usual arithmetic conversions are performed on the control
expression, but the result must have an integral type. For more
information about data-type conversion, see Section 6.10. The switch
statement is typically a
compound statement, within which are one or more case
statements executed if the control expression matches the
case
. The syntax for a case
label and
expression follows:
case constant-expression : statement
The constant expression must have an integral type. No
two case
labels can specify the same value.
There is no limit on the number of
case
labels in a switch
statement.
Only one statement in the compound statement can have the following label:
default :
The case
and default
labels can occur in
any order, but it is common practice for the default
statement to follow the case
statements. Note that
execution flows from the selected case into the cases following
unless explicit action is taken, such as a break
statement.
When the switch
statement is executed, the following
sequence takes place:
switch
control expression is evaluated
(and integral promotions applied) and compared with the constant
expressions in the case
labels.
case
label, control transfers to the
statement following that label. If a break
statement is encountered, the switch
statement terminates; otherwise, execution continues into
the following case
or default statements
until a break
statement or the end of the
switch
statement is encountered (see Example 7-1).
A switch
statement can also be terminated
by a return
or goto
statement.
If a switch
statement is inside a loop,
the switch
statement is terminated if a
continue
statement terminates the loop. See Section 7.7 for more information
about these statements.
case
label, and there is a default
label, control is transferred to the statement following that
label. If a break
statement does not end the
default
statement, and a case
label
follows, that case
statement is executed.
case
label and there is no default
label, execution of the switch
statement
terminates.
Example 7-1 uses the
switch
statement to count blanks, tabs, and new-line
characters entered from the terminal.
/* This program counts blanks, tabs, and new lines in text * * entered from the keyboard. */ #include <stdio.h> main() { int number_tabs = 0, number_lines = 0, number_blanks = 0; int ch; while ((ch = getchar()) != EOF) switch (ch) { case '\t': ++number_tabs; break; case '\n': ++number_lines; break; case ' ' : ++number_blanks; break; default:; } printf("Blanks\tTabs\tNewlines\n"); printf("%6d\t%6d\t%6d\n", number_blanks, number_tabs,number_lines); }
Key to Example 7-1:
case
statements is used
to increment separate counters depending on the character
encountered.
break
statement causes control to
return to the while
loop. Control is passed to the
while
loop if the value of ch
does not
match any of the case
constant expressions.
Without the break
statements, each case
would drop through to the next.
If variable declarations appear in the compound statement within
a switch
statement, initializers on auto
or register
declarations are ineffective. However,
initializations within the statements following a case
are effective. Consider the following example:
switch (ch) { int nx = 1; /* Initialization ignored */ printf("%d", n); /* This first printf is not executed */ case 'a' : { int n = 5; /* Proper initialization occurs */ printf("%d", n); break; } case 'b' : { break; } default : { break; } }
In this example, if ch == 'a'
, then the program
prints the value 5. If the variable equals any other letter, the
program prints nothing because the initialization occurs outside
of the case
label, and statements outside of the
case
label are ineffective.