Docs

README

switch-case Statement

πŸ“– Introduction

The switch statement provides an efficient way to select one of many code blocks to execute based on the value of an expression. It's an alternative to long if-else if chains when testing a single variable against multiple constant values.


🎯 switch vs if-else

           Multiple Conditions on Same Variable
                         β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                               β”‚
    if-else if                        switch
         β”‚                               β”‚
    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Flexible β”‚                  β”‚ Value-based   β”‚
    β”‚ ranges   β”‚                  β”‚ Jump table    β”‚
    β”‚ complex  β”‚                  β”‚ Faster        β”‚
    β”‚ conditionsβ”‚                  β”‚ cleaner      β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Basic Syntax

switch (expression) {
    case constant1:
        // Code for constant1
        break;
    case constant2:
        // Code for constant2
        break;
    case constant3:
        // Code for constant3
        break;
    default:
        // Code if no case matches
        break;
}

Key Components:

ComponentDescription
switch (expression)Expression to evaluate (must be integral type)
case constant:Label for a specific value
break;Exits the switch block
default:Optional - handles unmatched values

πŸ”„ How switch Works

     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚ Evaluate        β”‚
     β”‚ expression      β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
              β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚ Compare with    β”‚
     β”‚ case 1?         │──Yes──► Execute case 1
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
              β”‚ No                      β”‚ break?
              β–Ό                         β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         Exit switch
     β”‚ Compare with    β”‚
     β”‚ case 2?         │──Yes──► Execute case 2
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
              β”‚ No                      β”‚ break?
              β–Ό                         β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         Exit switch
     β”‚ Compare with    β”‚
     β”‚ case 3?         │──Yes──► Execute case 3
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚ No
              β–Ό
     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
     β”‚ Execute default β”‚
     β”‚ (if present)    β”‚
     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‹ Simple Examples

Example 1: Day of Week

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("Invalid day\n");
        break;
}

Example 2: Grade Message

char grade = 'B';

switch (grade) {
    case 'A':
        printf("Excellent!\n");
        break;
    case 'B':
        printf("Good job!\n");
        break;
    case 'C':
        printf("Satisfactory\n");
        break;
    case 'D':
        printf("Need improvement\n");
        break;
    case 'F':
        printf("Failed\n");
        break;
    default:
        printf("Invalid grade\n");
        break;
}

⚠️ The break Statement

break is crucial in switch statements. Without it, execution "falls through" to the next case.

Without break (Fall-through):

int num = 1;

switch (num) {
    case 1:
        printf("One\n");
        // No break - falls through!
    case 2:
        printf("Two\n");
        // No break - falls through!
    case 3:
        printf("Three\n");
        break;
    default:
        printf("Other\n");
}

// Output:
// One
// Two
// Three

With break (Correct):

int num = 1;

switch (num) {
    case 1:
        printf("One\n");
        break;
    case 2:
        printf("Two\n");
        break;
    case 3:
        printf("Three\n");
        break;
    default:
        printf("Other\n");
}

// Output:
// One

πŸ”€ Intentional Fall-through

Sometimes fall-through is useful for grouping cases:

Example: Weekday vs Weekend

int day = 6;

switch (day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        printf("Weekday\n");
        break;
    case 6:
    case 7:
        printf("Weekend\n");
        break;
    default:
        printf("Invalid day\n");
}

Example: Days in Month

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;  // Ignoring leap year
        break;
    default:
        days = 0;
}

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

πŸ“Š Allowed Data Types

The switch expression must be an integral type:

AllowedNot Allowed
intfloat
chardouble
shortstring
longarray
enumpointer
unsigned typesstruct

Valid Examples:

// Integer
switch (intVar) { ... }

// Character
switch (charVar) { ... }

// Enum
enum Color { RED, GREEN, BLUE };
enum Color c = RED;
switch (c) { ... }

// Expression that evaluates to integer
switch (a + b) { ... }
switch (x % 3) { ... }

Invalid Examples:

// ERROR: float not allowed
float f = 1.5;
switch (f) { ... }  // Compilation error

// ERROR: string not allowed
char *str = "hello";
switch (str) { ... }  // Compilation error

πŸ—οΈ Case Labels Must Be Constants

Case labels must be compile-time constants:

// CORRECT: Constants
switch (x) {
    case 1:          // Integer literal
    case 'A':        // Character literal
    case 1 + 2:      // Constant expression
    case RED:        // Enum value
}

// WRONG: Variables
int a = 5;
switch (x) {
    case a:  // ERROR: 'a' is not a constant
}

// CORRECT with const (C99+)
const int MAX = 100;
switch (x) {
    case 100:  // OK
    // case MAX:  // May not work in all compilers
}

πŸ“ The default Case

default handles all unmatched values:

int option = 5;

switch (option) {
    case 1:
        printf("Option 1\n");
        break;
    case 2:
        printf("Option 2\n");
        break;
    default:
        printf("Invalid option: %d\n", option);
        break;
}

default Position:

  • β€’Can be anywhere in switch
  • β€’Convention: place at the end
  • β€’break in default is optional but recommended
// default in middle (works, but not recommended)
switch (x) {
    case 1:
        // ...
        break;
    default:
        // ...
        break;
    case 2:
        // ...
        break;
}

πŸ”§ Nested switch Statements

You can nest switch statements:

int category = 1;
int subcategory = 2;

switch (category) {
    case 1:
        printf("Category 1: ");
        switch (subcategory) {
            case 1:
                printf("Sub A\n");
                break;
            case 2:
                printf("Sub B\n");
                break;
            default:
                printf("Unknown sub\n");
        }
        break;
    case 2:
        printf("Category 2\n");
        break;
    default:
        printf("Unknown category\n");
}

⚑ Performance Comparison

if-else Chain:

if (x == 1) {
    // ...
} else if (x == 2) {
    // ...
} else if (x == 3) {
    // ...
} else if (x == 4) {
    // ...
}
// Time: O(n) - linear search

switch Statement:

switch (x) {
    case 1: // ...
    case 2: // ...
    case 3: // ...
    case 4: // ...
}
// Time: O(1) - often uses jump table

Note: Modern compilers optimize both, but switch can be faster for many consecutive integer cases.


πŸ”„ Using switch with Enums

switch works naturally with enums:

enum MenuOption {
    NEW_FILE,
    OPEN_FILE,
    SAVE_FILE,
    EXIT
};

enum MenuOption choice = OPEN_FILE;

switch (choice) {
    case NEW_FILE:
        printf("Creating new file...\n");
        break;
    case OPEN_FILE:
        printf("Opening file...\n");
        break;
    case SAVE_FILE:
        printf("Saving file...\n");
        break;
    case EXIT:
        printf("Goodbye!\n");
        break;
}

Enum with Default:

// Good practice: handle future enum additions
switch (color) {
    case RED:
        // ...
        break;
    case GREEN:
        // ...
        break;
    case BLUE:
        // ...
        break;
    default:
        // Handle unknown color (future-proofing)
        printf("Unknown color\n");
        break;
}

πŸ“ Menu System Pattern

Common use case for switch:

#include <stdio.h>

int main() {
    int choice;

    printf("===== MENU =====\n");
    printf("1. Add Item\n");
    printf("2. View Items\n");
    printf("3. Delete Item\n");
    printf("4. Exit\n");
    printf("Enter choice: ");
    scanf("%d", &choice);

    switch (choice) {
        case 1:
            printf("Adding item...\n");
            // addItem();
            break;
        case 2:
            printf("Viewing items...\n");
            // viewItems();
            break;
        case 3:
            printf("Deleting item...\n");
            // deleteItem();
            break;
        case 4:
            printf("Exiting...\n");
            break;
        default:
            printf("Invalid choice! Please try again.\n");
    }

    return 0;
}

⚠️ Common Mistakes

1. Forgetting break:

// Bug: falls through
switch (x) {
    case 1:
        printf("One");
    case 2:
        printf("Two");  // Also prints for case 1!
}

2. Using non-constant case:

int val = 5;
switch (x) {
    case val:  // ERROR!
        break;
}

3. Duplicate case values:

switch (x) {
    case 1:
        break;
    case 1:  // ERROR: duplicate case
        break;
}

4. Declaring variables in case:

switch (x) {
    case 1:
        int y = 10;  // ERROR in some compilers
        break;
}

// Solution: use braces
switch (x) {
    case 1: {
        int y = 10;  // OK
        break;
    }
}

βœ… When to Use switch

Use switch when:

  • β€’Testing one variable against many constants
  • β€’Values are discrete (integers, chars, enums)
  • β€’Code for each case is independent
  • β€’Many cases map to same code (fall-through)

Use if-else when:

  • β€’Conditions involve ranges
  • β€’Conditions involve different variables
  • β€’Conditions use logical operators
  • β€’Floating-point comparisons needed

switch is Good:

switch (command) {
    case 'q': quit(); break;
    case 's': save(); break;
    case 'l': load(); break;
}

if-else is Better:

if (score >= 90) {
    grade = 'A';
} else if (score >= 80) {
    grade = 'B';
}
// Range checks - cannot use switch

πŸ”‘ Key Takeaways

  1. β€’switch evaluates an integral expression
  2. β€’case labels must be compile-time constants
  3. β€’break prevents fall-through
  4. β€’default handles unmatched values
  5. β€’Fall-through can be intentional for grouping
  6. β€’Variables declared in case need braces {}
  7. β€’switch can be faster than if-else chains
  8. β€’Best for discrete value checking

⏭️ Next Topic

Continue to Loops (for, while, do-while) to learn about repetition in C.

README - C Programming Tutorial | DeepML