A instrução switch é uma estrutura de controle de fluxo em C que permite selecionar uma entre múltiplas opções com base no valor de uma expressão inteira. Ela é frequentemente usada como alternativa a uma cadeia de if-else quando se deseja comparar uma variável com vários valores constantes.

Nesta aula, exploraremos a sintaxe completa, o comportamento de fall-through (passagem automática para o próximo caso), a cláusula default e as limitações que devem ser consideradas ao usar switch.

Sintaxe

A sintaxe básica do switch é:

switch (expressão) {
    case constante1:
        // comandos
        break;
    case constante2:
        // comandos
        break;
    // ...
    default:
        // comandos
}

A expressão deve ser de tipo inteiro (incluindo char, int, enum) e as constantes dos case devem ser expressões constantes inteiras. Cada case é rotulado com um valor único. O fluxo de execução começa no case que corresponde ao valor da expressão e continua até encontrar um break ou o final do bloco.

Exemplo simples:

int opcao = 2;
switch (opcao) {
    case 1:
        printf("Opção 1\n");
        break;
    case 2:
        printf("Opção 2\n");
        break;
    case 3:
        printf("Opção 3\n");
        break;
    default:
        printf("Opção inválida\n");
}

break e fall-through

A instrução break é usada para sair do bloco switch. Sem ela, a execução continua para o próximo case, fenômeno conhecido como fall-through. O fall-through pode ser intencional para executar o mesmo código para múltiplos valores.

Exemplo de fall-through intencional:

char letra = 'a';
switch (letra) {
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
        printf("Vogal\n");
        break;
    default:
        printf("Consoante\n");
}

Nesse caso, se letra for 'a', 'e', 'i', 'o' ou 'u', a execução cai no case 'u' (após percorrer os anteriores) e imprime "Vogal". É importante lembrar que o fall-through pode causar bugs se não for planejado; por isso, muitos programadores sempre incluem break a menos que queiram explicitamente o fall-through.

default

A cláusula default é opcional e especifica o que fazer quando o valor da expressão não coincide com nenhum case. Ela pode aparecer em qualquer posição dentro do switch, mas geralmente é colocada ao final. Se não houver default e nenhum case for correspondido, nenhuma ação é tomada.

Exemplo com default:

int numero = 5;
switch (numero) {
    case 1:
        printf("Um\n");
        break;
    case 2:
        printf("Dois\n");
        break;
    default:
        printf("Outro número\n");
}

É uma boa prática incluir default para tratar valores inesperados, mesmo que não faça nada, como documentação.

Limitações

A instrução switch tem algumas limitações importantes:

  • Os valores dos case devem ser constantes inteiras (literais ou expressões constantes). Não é possível usar variáveis ou expressões não constantes.
  • Não é possível usar intervalos (como case 1..5) diretamente; é necessário listar cada valor ou usar fall-through.
  • A expressão do switch deve ser de tipo inteiro; não funciona com float, double ou strings.
  • O número de case pode ser grande, mas o código pode ficar verboso.
  • O comportamento de fall-through pode ser fonte de bugs se não for gerenciado com cuidado.

Para contornar algumas limitações, muitas vezes se usa if-else ou tabelas de funções.

Boas práticas

  • Sempre inclua break ao final de cada case, a menos que o fall-through seja intencional e documentado.
  • Use default para capturar valores inesperados.
  • Mantenha os case em ordem lógica (numérica ou alfabética).
  • Evite case com muitos comandos; considere chamar funções.

Referências

Exercícios

  1. Escreva um programa que leia um número de 1 a 7 e imprima o dia da semana correspondente (1 = Domingo, 2 = Segunda, etc.). Use switch.

    ✓ Resposta:
    #include <stdio.h>
    int main() {
        int dia;
        printf("Digite um número de 1 a 7: ");
        scanf("%d", &dia);
        switch (dia) {
            case 1: printf("Domingo\n"); break;
            case 2: printf("Segunda-feira\n"); break;
            case 3: printf("Terça-feira\n"); break;
            case 4: printf("Quarta-feira\n"); break;
            case 5: printf("Quinta-feira\n"); break;
            case 6: printf("Sexta-feira\n"); break;
            case 7: printf("Sábado\n"); break;
            default: printf("Número inválido\n");
        }
        return 0;
    }
  2. Usando fall-through, escreva um programa que leia uma letra e indique se é vogal ou consoante (considere apenas letras minúsculas).

    ✓ Resposta:
    #include <stdio.h>
    int main() {
        char letra;
        printf("Digite uma letra minúscula: ");
        scanf(" %c", &letra);
        switch (letra) {
            case 'a':
            case 'e':
            case 'i':
            case 'o':
            case 'u':
                printf("Vogal\n");
                break;
            default:
                printf("Consoante\n");
        }
        return 0;
    }
  3. Crie um programa que leia um caractere e, usando switch, imprima se é um dígito (0-9), letra maiúscula (A-Z) ou outro. Dica: use os valores ASCII.

    ✓ Resposta:
    #include <stdio.h>
    int main() {
        char ch;
        printf("Digite um caractere: ");
        scanf(" %c", &ch);
        switch (ch) {
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
                printf("Dígito\n");
                break;
            case 'A': case 'B': case 'C': case 'D': case 'E':
            case 'F': case 'G': case 'H': case 'I': case 'J':
            case 'K': case 'L': case 'M': case 'N': case 'O':
            case 'P': case 'Q': case 'R': case 'S': case 'T':
            case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
                printf("Letra maiúscula\n");
                break;
            default:
                printf("Outro\n");
        }
        return 0;
    }
  4. Escreva um programa que simule uma calculadora simples com as operações +, -, *, /. Use switch com base no operador lido.

    ✓ Resposta:
    #include <stdio.h>
    int main() {
        double a, b, resultado;
        char operador;
        printf("Digite a expressão (ex: 3 + 4): ");
        scanf("%lf %c %lf", &a, &operador, &b);
        switch (operador) {
            case '+':
                resultado = a + b;
                printf("Resultado: %.2f\n", resultado);
                break;
            case '-':
                resultado = a - b;
                printf("Resultado: %.2f\n", resultado);
                break;
            case '*':
                resultado = a * b;
                printf("Resultado: %.2f\n", resultado);
                break;
            case '/':
                if (b != 0) {
                    resultado = a / b;
                    printf("Resultado: %.2f\n", resultado);
                } else {
                    printf("Erro: divisão por zero\n");
                }
                break;
            default:
                printf("Operador inválido\n");
        }
        return 0;
    }
  5. Explique por que o código abaixo pode não se comportar como esperado e corrija-o:

    int x = 2;
    switch (x) {
        case 1:
            printf("um\n");
        case 2:
            printf("dois\n");
        case 3:
            printf("três\n");
    }

    ✓ Resposta:

    O código tem fall-through não intencional: quando x é 2, imprime "dois" e "três" porque não há break. Para corrigir, adicione break após cada case:

    int x = 2;
    switch (x) {
        case 1:
            printf("um\n");
            break;
        case 2:
            printf("dois\n");
            break;
        case 3:
            printf("três\n");
            break;
    }