Skip to content

C switch Statement

Updated 7 min read Aimerscrew

Some decisions are really one question with many fixed answers: which button was pressed, which menu option was chosen, which day of the week it is. The C switch statement handles exactly this kind of choice. In this lesson, you'll learn how switch, case, break and default work together, and how to avoid the "fall-through" bug that surprises almost everyone the first time.

🌍 Real-life example

A vending machine doesn't run through a list of "is it A? is it B? is it C?" questions in your head. You press B and it goes straight to slot B. A switch works the same way: it takes one value and jumps directly to the matching case.

What is a switch statement in C?

A switch statement picks one of several blocks of code based on the value of a single integer expression. Here's the general shape:

switch (expression) {
    case VALUE_1:
        // statements for VALUE_1
        break;
    case VALUE_2:
        // statements for VALUE_2
        break;
    default:
        // statements when nothing matched
        break;
}
  • switch (expression): the value being tested, such as a variable.
  • case VALUE:: a label. If the expression equals this value, execution starts here.
  • break;: jumps out of the switch, to the first line after its closing brace.
  • default:: optional; runs when no case matches, like the final else in an if chain.

A first example: days of the week

#include <stdio.h>

int main(void) {
    int day = 3;

    switch (day) {
        case 1:
            printf("Monday\n");
            break;
        case 2:
            printf("Tuesday\n");
            break;
        case 3:
            printf("Wednesday\n");
            break;
        case 4:
            printf("Thursday\n");
            break;
        case 5:
            printf("Friday\n");
            break;
        case 6:
            printf("Saturday\n");
            break;
        case 7:
            printf("Sunday\n");
            break;
        default:
            printf("Not a valid day\n");
            break;
    }

    return 0;
}
Wednesday

C evaluates day once, jumps to case 3:, prints Wednesday, and the break sends it out of the switch. Try day = 9 and you'll see Not a valid day.

What can a case label be?

Case labels have strict rules:

  • They must be integer constants: numbers like 3, characters like 'B' (a char is a small integer), or names created with #define, which you met in C constants.
  • They can't be variables, ranges (case score >= 90: is not allowed), decimal numbers or strings.
  • Two cases in the same switch can't have the same value. GCC reports duplicate case value.

Because characters count as integers, switch is perfect for a vending machine keypad:

#include <stdio.h>

int main(void) {
    char button = 'B';

    switch (button) {
        case 'A':
            printf("Water - $1.25\n");
            break;
        case 'B':
            printf("Orange juice - $2.50\n");
            break;
        case 'C':
            printf("Chips - $1.75\n");
            break;
        default:
            printf("Unknown button, please try again\n");
            break;
    }

    return 0;
}
Orange juice - $2.50

What happens if you forget break? (fall-through)

A case label only marks where execution starts. It doesn't mark where it stops. Without a break, C keeps going straight into the next case's code, and the next, until it reaches a break or the end of the switch. This is called fall-through.

Here's a bank menu where every break was forgotten. The user chose option 2:

#include <stdio.h>

int main(void) {
    int choice = 2;

    switch (choice) {
        case 1:
            printf("Checking balance...\n");
        case 2:
            printf("Depositing money...\n");
        case 3:
            printf("Withdrawing money...\n");
        default:
            printf("Goodbye!\n");
    }

    return 0;
}
Depositing money...
Withdrawing money...
Goodbye!

The program jumped to case 2 correctly, then fell through cases 3 and default as well. The customer wanted to deposit, but the program also "withdrew" money. GCC catches this with -Wextra: warning: this statement may fall through.

Two switch statements with choice = 2. On the left, with break, C jumps to case 2, runs it, then break jumps to after the switch. On the right, without break, C jumps to case 2 and then runs case 3 and default too.
switch jumps straight to the matching case. break exits; without it, execution falls through to the cases below.

Grouping cases that share code

Fall-through has a useful side. When several values need the same code, stack their labels on top of each other. Empty labels fall through to the shared code, and GCC doesn't warn about this pattern:

#include <stdio.h>

int main(void) {
    int day = 6;

    switch (day) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            printf("Weekday: the gym opens at 6 AM.\n");
            break;
        case 6:
        case 7:
            printf("Weekend: the gym opens at 8 AM.\n");
            break;
        default:
            printf("Invalid day number.\n");
            break;
    }

    return 0;
}
Weekend: the gym opens at 8 AM.

Using fall-through on purpose

Sometimes falling through is exactly what you want. In an airline loyalty program, a gold member gets every silver perk plus more, and a silver member gets every bronze perk plus more. Start at the member's tier and let execution fall down through the lower tiers:

#include <stdio.h>

int main(void) {
    int tier = 2;   /* 1 = bronze, 2 = silver, 3 = gold */

    printf("Your perks:\n");

    switch (tier) {
        case 3:
            printf("- Free airport lounge access\n");
            /* fall through */
        case 2:
            printf("- Free checked bag\n");
            /* fall through */
        case 1:
            printf("- Priority boarding\n");
            break;
        default:
            printf("- No perks yet\n");
            break;
    }

    return 0;
}
Your perks:
- Free checked bag
- Priority boarding

The /* fall through */ comment tells other programmers (and GCC, which recognizes it and stays quiet) that the missing break is intentional.

💡 Tip

Always put a break after the last case and after default too, even though nothing comes below them. If someone adds a new case later, they won't create an accidental fall-through.

Real-world example: a simple calculator

A switch on an operator character is a classic way to build a calculator. Notice that a case can contain any code, including an if statement:

#include <stdio.h>

int main(void) {
    double a = 12.0;
    double b = 4.0;
    char op = '/';

    switch (op) {
        case '+':
            printf("%.1f + %.1f = %.1f\n", a, b, a + b);
            break;
        case '-':
            printf("%.1f - %.1f = %.1f\n", a, b, a - b);
            break;
        case '*':
            printf("%.1f * %.1f = %.1f\n", a, b, a * b);
            break;
        case '/':
            if (b != 0.0) {
                printf("%.1f / %.1f = %.1f\n", a, b, a / b);
            } else {
                printf("Cannot divide by zero.\n");
            }
            break;
        default:
            printf("Unknown operator: %c\n", op);
            break;
    }

    return 0;
}
12.0 / 4.0 = 3.0

You'll turn this into a full interactive program in the calculator project.

switch vs if else: which should you use?

SituationBest choice
One integer or char compared against many exact valuesswitch
Ranges, like score >= 90if / else if
Decimal numbers (double, float) or stringsif / else if
Conditions on several different variablesif / else if
Several values sharing the same codeswitch with grouped cases

Anything a switch does, an if else chain can do too. A switch is simply cleaner when you're matching one value against a menu of options, and compilers can often turn it into a fast jump table.

Common mistakes with switch

1. Forgetting break

The most common switch bug by far. Unless you're grouping cases or falling through on purpose (with a comment), every case should end with break.

2. Using a range or a variable as a label

switch (score) {
    case score >= 90:   // error: not a constant
        printf("A\n");
        break;
}

Case labels must be fixed integer values known when the program is compiled. Use an if else chain for ranges.

3. Switching on a string or a double

switch (name) where name holds text, or switch (price) where price is a double, won't compile. GCC says switch quantity not an integer.

4. Declaring a variable right after a case label

Before C23, a label had to be followed by a statement, not a declaration, so case 1: int total = 0; is rejected or warned about by many compilers. It also creates a variable that every later case can see. Wrap the case's code in braces instead: case 1: { int total = 0; ... break; }.

Practice exercise

🏋️ Try it yourself

A parking garage charges by vehicle type: 'M' (motorcycle) pays $3, 'C' (car) pays $8, and 'T' (truck) pays $15. Lowercase letters should work too. Store the type in a char (try 'c') and print the fee, or Unknown vehicle type for anything else.

Show solution
#include <stdio.h>

int main(void) {
    char vehicle = 'c';

    switch (vehicle) {
        case 'M':
        case 'm':
            printf("Motorcycle: $3\n");
            break;
        case 'C':
        case 'c':
            printf("Car: $8\n");
            break;
        case 'T':
        case 't':
            printf("Truck: $15\n");
            break;
        default:
            printf("Unknown vehicle type\n");
            break;
    }

    return 0;
}
Car: $8

What's next?

For a quick choice between just two values, there's an even shorter tool than if else. Next, learn the C ternary operator.

Key takeaways

  • A switch compares one integer expression against constant case labels and jumps to the match.
  • Case labels must be integer constants such as 3, 'B' or a #define name; no ranges, variables, doubles or strings.
  • break exits the switch; without it, execution falls through into the next case.
  • default runs when no case matches, like the final else in an if chain.
  • Stack several case labels to share one block of code, and mark intentional fall-through with a comment.
  • Use switch for exact matches on one value and if else for ranges or complex conditions.

Frequently asked questions

What happens if there is no break in a switch case in C?

Execution continues into the next case's code, and the one after that, until a break or the end of the switch. This is called fall-through. GCC warns about it with -Wextra unless a fall through comment marks it as intentional.

Can you use a string in a C switch statement?

No. The switch expression and case labels must be integers, and characters count as integers. To choose based on text, use an if else chain with strcmp().

Is default required in a switch statement?

No, default is optional. If it is missing and no case matches, the switch simply does nothing. Including a default is good practice for catching unexpected values.

Is switch faster than if else in C?

Often slightly, because the compiler can turn a switch with many cases into a jump table. For beginners, readability matters more: use switch when you match one value against many exact options.

Can two case labels have the same value?

No. Each case value in a switch must be unique, otherwise GCC reports a duplicate case value error.