# 7.5 Selection Statements

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.

## 7.5.1 The if Statement

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);
}
```

## 7.5.2 The switch Statement

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:

1. The `switch` control expression is evaluated (and integral promotions applied) and compared with the constant expressions in the `case` labels.

2. If the control expression's value matches a `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.

3. If the control expression's value does not match any `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.

4. If the control expression's value does not match any `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.

### Example 7-1 Using switch to Count Blanks, Tabs, and New Lines

```/*  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:

1. A series of `case` statements is used to increment separate counters depending on the character encountered.

2. The `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.