The switch statement

A switch statement is a selection statement that lets you transfer control to different statements within the switch body depending on the value of the switch expression. The switch expression must evaluate to an integral or enumeration value. The body of the switch statement contains case clauses that consist of

If the value of the switch expression equals the value of one of the case expressions, the statements following that case expression are processed. If not, the default label statements, if any, are processed.

Read syntax diagramSkip visual syntax diagramswitch statement syntax
 
>>-switch--(--expression--)--switch_body-----------------------><
 

The switch body is enclosed in braces and can contain definitions, declarations, case clauses, and a default clause. Each case clause and default clause can contain statements.

Read syntax diagramSkip visual syntax diagram      .----------------------------------.
      V                                  |
>>-{----+------------------------------+-+---------------------->
        +-type_definition--------------+
        +-file_scope_data_declaration--+
        '-block_scope_data_declaration-'
 
   .-----------------.
   V                 |
>----+-------------+-+--+----------------+---------------------->
     '-case_clause-'    '-default_clause-'
 
   .-----------------.
   V                 |
>----+-------------+-+--}--------------------------------------><
     '-case_clause-'
 
Note:
An initializer within a type_definition, file_scope_data_declaration or block_scope_data_declaration is ignored.

A case clause contains a case label followed by any number of statements. A case clause has the form:

Read syntax diagramSkip visual syntax diagramCase clause syntax
 
               .-----------.
               V           |
>>-case_label----statement-+-----------------------------------><
 

A case label contains the word case followed by an integral constant expression and a colon. The value of each integral constant expression must represent a different value; you cannot have duplicate case labels. Anywhere you can put one case label, you can put multiple case labels. A case label has the form:

Read syntax diagramSkip visual syntax diagramcase label syntax
 
   .---------------------------------------.
   V                                       |
>>---case--integral_constant_expression--:-+-------------------><
 

A default clause contains a default label followed by one or more statements. You can put a case label on either side of the default label. A switch statement can have only one default label. A default_clause has the form:

Read syntax diagramSkip visual syntax diagramDefault clause statement
 
                                               .-----------.
                                               V           |
>>-+------------+--default--:--+------------+----statement-+---><
   '-case_label-'              '-case_label-'
 

The switch statement passes control to the statement following one of the labels or to the statement following the switch body. The value of the expression that precedes the switch body determines which statement receives control. This expression is called the switch expression.

The value of the switch expression is compared with the value of the expression in each case label. If a matching value is found, control is passed to the statement following the case label that contains the matching value. If there is no matching value but there is a default label in the switch body, control passes to the default labelled statement. If no matching value is found, and there is no default label anywhere in the switch body, no part of the switch body is processed.

When control passes to a statement in the switch body, control only leaves the switch body when a break statement is encountered or the last statement in the switch body is processed.

If necessary, an integral promotion is performed on the controlling expression, and all expressions in the case statements are converted to the same type as the controlling expression. The switch expression can also be of class type if there is a single conversion to integral or enumeration type.

Compiling with option -qinfo=gen finds case labels that fall through when they should not.

Restrictions on switch statements

You can put data definitions at the beginning of the switch body, but the compiler does not initialize auto and register variables at the beginning of a switch body. You can have declarations in the body of the switch statement.

You cannot use a switch statement to jump over initializations.

When the scope of an identifier with a variably modified type includes a case or default label of a switch statement, the entire switch statement is considered to be within the scope of that identifier. That is, the declaration of the identifier must precede the switch statement.

C++ In C++, you cannot transfer control over a declaration containing an explicit or implicit initializer unless the declaration is located in an inner block that is completely bypassed by the transfer of control. All declarations within the body of a switch statement that contain initializers must be contained in an inner block.

Examples of switch statements

The following switch statement contains several case clauses and one default clause. Each clause contains a function call and a break statement. The break statements prevent control from passing down through each statement in the switch body.

If the switch expression evaluated to '/', the switch statement would call the function divide. Control would then pass to the statement following the switch body.

char key;

printf("Enter an arithmetic operator\n");
scanf("%c",&key);

switch (key)
{
   case '+':
      add();
      break;

   case '-':
      subtract();
      break;

   case '*':
      multiply();
      break;

   case '/':
      divide();
      break;

   default:
      printf("invalid key\n");
      break;
}

If the switch expression matches a case expression, the statements following the case expression are processed until a break statement is encountered or the end of the switch body is reached. In the following example, break statements are not present. If the value of text[i] is equal to 'A', all three counters are incremented. If the value of text[i] is equal to 'a', lettera and total are increased. Only total is increased if text[i] is not equal to 'A' or 'a'.

char text[100];
int capa, lettera, total;

// ...

for (i=0; i<sizeof(text); i++) {

    switch (text[i])
    {
       case 'A':
         capa++;
       case 'a':
         lettera++;
       default:
         total++;
    }
}

The following switch statement performs the same statements for more than one case label:

/**
 ** This example contains a switch statement that performs
 ** the same statement for more than one case label.
 **/

#include <stdio.h>

int main(void)
{
  int month;

  /* Read in a month value */
  printf("Enter month: ");
  scanf("%d", &month);

  /* Tell what season it falls into */
  switch (month)
  {
     case 12:
     case 1:
     case 2:
        printf("month %d is a winter month\n", month);
        break;

     case 3:
     case 4:
     case 5:
        printf("month %d is a spring month\n", month);
        break;

     case 6:
     case 7:
     case 8:
        printf("month %d is a summer month\n", month);
        break;

     case 9:
     case 10:
     case 11:
        printf("month %d is a fall month\n", month);
        break;

     case 66:
     case 99:
     default:
        printf("month %d is not a valid month\n", month);
  }

  return(0);
}

If the expression month has the value 3, control passes to the statement:

printf("month %d is a spring month\n",
month);

The break statement passes control to the statement following the switch body.

Related information