C Programming · September 15, 2026

The switch Statement — and switch vs. if-else Ladder

Module I · Decision and Case Control · Lectures 15–16


🎯 Why This Matters

The last post ended with a warning: an if-else-if ladder longer than 5–6 steps starts getting hard to read. switch is C’s answer to exactly that problem — a cleaner way to test one variable against a list of exact values, built specifically for menus, day names, grade letters, and anything else with a fixed set of discrete options. This post covers switch in full, then puts it head-to-head against the if-else ladder so you know exactly when to reach for each one — matching this lecture’s comparative coding exercise.

🔷 Basic switch Syntax

#include <stdio.h>

int main() {
    int day = 3;

    switch (day) {
        case 1:
            printf("Monday\n");
            break;
        case 2:
            printf("Tuesday\n");
            break;
        case 3:
            printf("Wednesday\n");
            break;
        default:
            printf("Invalid day\n");
    }

    return 0;
}

🖥️ Output:
Wednesday

C evaluates day once, then jumps directly to the matching case label — case 3: — and runs everything from there until it hits break. The default case, similar to else in an if-else ladder, catches any value that didn’t match any listed case.

Example 2: Menu-Driven Calculator (This Lecture’s Activity)

#include <stdio.h>

int main() {
    int choice;
    float a, b;

    printf("1-Add 2-Sub 3-Mul 4-Div\n");
    printf("Enter choice: ");
    scanf("%d", &choice);

    printf("Enter two numbers: ");
    scanf("%f %f", &a, &b);

    switch (choice) {
        case 1:
            printf("Result: %.2f\n", a + b);
            break;
        case 2:
            printf("Result: %.2f\n", a - b);
            break;
        case 3:
            printf("Result: %.2f\n", a * b);
            break;
        case 4:
            printf("Result: %.2f\n", a / b);
            break;
        default:
            printf("Invalid choice\n");
    }

    return 0;
}

🖥️ Sample run:
1-Add 2-Sub 3-Mul 4-Div
Enter choice: 3
Enter two numbers: 6 7
Result: 42.00

This is the exact same calculator concept from the Algorithms post’s Algorithm 11 — but where that version used nested “Go to Step X” jumps, a switch expresses “jump straight to the matching branch” far more directly, since that’s precisely what switch was designed to do.

⚠️ Fall-Through: The Behavior You Must Understand

Here’s the single most important thing to know about switch: matching a case doesn’t automatically stop execution. Without break, C keeps running every line below the matched case — straight through any following cases — until it hits a break or reaches the end of the switch.

#include <stdio.h>

int main() {
    int n = 2;

    switch (n) {
        case 1:
            printf("A");
            break;
        case 2:
            printf("B");
        case 3:
            printf("C");
            break;
        default:
            printf("D");
    }

    return 0;
}

🖥️ Output:
BC

Notice case 2 has no break — so after printing "B", execution falls straight into case 3 and prints "C" too, only stopping once it reaches that case’s break. This is a real, deliberate feature of C — not a bug — but forgetting it is one of the most common beginner mistakes with switch.

Using Fall-Through on Purpose: Grouping Cases

Fall-through isn’t always a mistake — it’s genuinely useful when several different values should trigger the exact same action.

#include <stdio.h>

int main() {
    char grade = 'B';

    switch (grade) {
        case 'A':
        case 'B':
        case 'C':
            printf("Passed\n");
            break;
        case 'F':
            printf("Failed\n");
            break;
        default:
            printf("Invalid grade\n");
    }

    return 0;
}

🖥️ Output:
Passed

Stacking case 'A':, case 'B':, and case 'C': with no code or break between them means all three “fall through” into the same shared block below. This is the standard, intentional way to group multiple values under one action — a case with an empty body always falls through to the next one, on purpose.

📋 Multiple Values, One Action: A Second Example

#include <stdio.h>

int main() {
    int month = 4;
    int days;

    switch (month) {
        case 1: case 3: case 5: case 7:
        case 8: case 10: case 12:
            days = 31;
            break;
        case 4: case 6: case 9: case 11:
            days = 30;
            break;
        case 2:
            days = 28;
            break;
        default:
            days = 0;
    }

    printf("Days in month %d: %d\n", month, days);

    return 0;
}

🖥️ Output:
Days in month 4: 30

Seven case labels share one days = 31; line, and four more share days = 30; — grouping cases like this is dramatically shorter than writing the equivalent as an if-else-if ladder with || chained across seven separate comparisons.

🚫 What switch Cannot Do

switch is powerful for the right job, but it comes with real restrictions that don’t apply to if-else.

#include <stdio.h>

int main() {
    float price = 49.99;

    // switch (price) { ... }       // INVALID — switch needs int or char
    // switch (price > 50) { ... }  // valid, but pointless — just use if

    if (price > 50.0) {
        printf("Expensive\n");
    } else {
        printf("Affordable\n");
    }

    return 0;
}

🖥️ Output:
Affordable

switch only works with int or char expressions — never float, double, or strings, and it can only test for exact equality, never a range like price > 50. This single restriction is the main reason the two tools aren’t interchangeable, and it’s the whole point of the comparison in the next section.

⚖️ switch vs. if-else Ladder: Solving the Same Problem Both Ways

Let’s build the exact same grade classifier from the last post — first as a ladder, then as a switch — and see directly where each one shines.

Version 1: if-else Ladder (Ranges)

#include <stdio.h>

int main() {
    int marks = 82;

    if (marks >= 90) {
        printf("Grade: A\n");
    } else if (marks >= 75) {
        printf("Grade: B\n");
    } else if (marks >= 50) {
        printf("Grade: C\n");
    } else {
        printf("Grade: F\n");
    }

    return 0;
}

🖥️ Output:
Grade: B

Version 2: The Same Problem as a switch — Doesn’t Work Directly

// This DOESN'T work the same way:
switch (marks) {
    case marks >= 90:   // INVALID — case needs a constant, not an expression
        ...
}

This is the key insight this lecture is built around: switch cannot test ranges at all — every case label must be a fixed, exact constant, known at compile time. A grade classifier based on ranges of marks is fundamentally an if-else problem, not a switch problem, no matter how you try to force it.

Version 3: A Problem switch Actually Fits — Grade Letter to Message

#include <stdio.h>

int main() {
    char grade = 'B';

    switch (grade) {
        case 'A':
            printf("Excellent!\n");
            break;
        case 'B':
            printf("Good job.\n");
            break;
        case 'C':
            printf("You passed.\n");
            break;
        default:
            printf("See me after class.\n");
    }

    return 0;
}

🖥️ Output:
Good job.

This is a natural switch problem — grade is a char, and every possible value is an exact, known constant ('A', 'B', 'C'). The lesson: the shape of the problem decides the tool. Testing ranges of a number → if-else. Testing exact matches of a small, known set of values → switch.

switchif-else ladder
Can test ranges?❌ No — exact match only✅ Yes
Can test compound conditions (&&, ||)?❌ No✅ Yes
Works with float/double/strings?❌ No — int/char only✅ Yes
Readable with many (10+) exact options?✅ Very❌ Gets messy fast
Needs a “stop” keyword?Yes — break, easy to forgetNo — each branch is automatically separate

🚫 Common Mistakes Beginners Make

MistakeWhy it happens
Forgetting breakExecution silently falls through into the next case — no compiler warning by default
Trying switch on a float or a rangeswitch only accepts int/char and only tests exact equality
Forgetting defaultAn unmatched value silently does nothing at all — no output, no error
Using a variable as a case labelcase requires a constant known at compile time, e.g. case 5: — not case x:

🎓 Practice Exercises

Exercise 1: Predict the Output

int x = 1;
switch (x) {
    case 1:
        printf("One");
    case 2:
        printf("Two");
        break;
    case 3:
        printf("Three");
}

(Answer: prints OneTwo — case 1 has no break, so it falls through into case 2, which does have one.)

Exercise 2: Choose the Right Tool

For each, decide whether switch or if-else fits better: (a) checking if a temperature is below freezing, (b) converting a menu digit 1–5 into an action, (c) checking if a username and password both match. (Answer: (a) if-else — a range. (b) switch — exact discrete values. (c) if-else — a compound condition with &&.)

Exercise 3: Build It Yourself

Write a switch statement that takes a single-character grade (A–F) and prints a GPA value for it (A→4.0, B→3.0, C→2.0, D→1.0, F→0.0), using default to catch anything else as invalid.

❓ Frequently Asked Questions

Q: Is switch faster than if-else?
Often, yes, for a large number of cases — a compiler can sometimes turn a switch with many sequential case values into a direct jump table, reaching the right branch in one step instead of testing conditions one by one. This isn’t guaranteed for every compiler or every switch, so it’s a nice bonus, not the main reason to choose it.

Q: Can case labels be out of order, like case 5: before case 1:?
Yes — case labels don’t need to be sequential or sorted; C just checks the expression against whichever labels exist, in any order they’re written.

Q: Why does C even allow dangerous fall-through instead of stopping automatically?
It’s a deliberate design choice from C’s early history — the grouped-cases example in this post (case 'A': case 'B': case 'C':) is a genuinely useful pattern that depends on fall-through working exactly this way. The tradeoff is that forgetting break elsewhere becomes a real risk.

✅ Key Takeaways

  • switch tests one int or char expression against a list of exact constant values — it cannot test ranges, compound conditions, or floating-point/string values.
  • Without break, execution falls through into every case below the matched one — a genuine C feature, and the most common source of switch bugs.
  • Stacking empty case labels (case 'A': case 'B':) is the standard, intentional way to group several values under one action.
  • Choose based on the shape of the problem: ranges and compound conditions → if-else; a small set of exact, discrete values → switch.
  • default plays the same role as a final else — catching anything that didn’t match any case — but unlike else, it’s easy to forget entirely, since switch doesn’t require one.

🚀 Next up: With every branching tool now covered — if, if-else, if-else-if, nested if, and switch — we’ll move into loops, starting with the while statement, where the “Go to Step X” jump-backward pattern from the Algorithms post finally becomes real, runnable C syntax.