Aula 09 – else-if, switch-case e Operador Ternário

Decisões múltiplas, seleção por valor e expressões condicionais compactas

Cadeia else-if — Múltiplas Condições

Quando há mais de dois caminhos possíveis, encadeamos blocos else if para testar condições em sequência. O fluxo percorre os testes de cima para baixo e executa o primeiro bloco cuja condição for verdadeira. Se nenhuma for, o else final (opcional) é executado.

if (condição1) {
    // executa se condição1 for verdadeira
} else if (condição2) {
    // executa se condição1 for falsa E condição2 for verdadeira
} else if (condição3) {
    // executa se condição1 e condição2 forem falsas E condição3 for verdadeira
} else {
    // executa se nenhuma condição acima for verdadeira (opcional)
}
Importante: Em uma cadeia else-if, apenas um dos blocos é executado por vez — assim que uma condição verdadeira é encontrada, os demais blocos são pulados completamente, mesmo que outras condições também fossem verdadeiras.

Exemplo: classificação de notas

#include <stdio.h>

int main() {
    float nota = 72.5;

    if (nota >= 90) {
        printf("Conceito A — Excelente\n");
    } else if (nota >= 80) {
        printf("Conceito B — Bom\n");
    } else if (nota >= 70) {
        printf("Conceito C — Regular\n");   // este executa
    } else if (nota >= 60) {
        printf("Conceito D — Insuficiente\n");
    } else {
        printf("Conceito F — Reprovado\n");
    }

    return 0;
}

Conceito C — Regular

DICA — ordem importa: As condições são avaliadas de cima para baixo. Coloque sempre as condições mais restritivas primeiro. No exemplo acima, se nota >= 60 viesse antes de nota >= 90, todo aluno com nota ≥ 60 seria classificado como "Insuficiente", mesmo os excelentes.

Exemplo do material de referência

#include <stdio.h>

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

    if (grade == 'A') {
        printf("Excellent!\n");
    } else if (grade == 'B') {
        printf("Good job.\n");   // este executa
    } else {
        printf("Needs improvement.\n");
    }

    return 0;
}

Good job.

Estrutura switch-case

O switch é uma alternativa mais eficiente e legível ao else-if quando se precisa comparar uma variável com múltiplos valores discretos e fixos. Em vez de avaliar condições booleanas, ele seleciona diretamente o caso correspondente ao valor da expressão.

switch (expressão) {
    case valor1:
        // bloco para valor1
        break;
    case valor2:
        // bloco para valor2
        break;
    default:
        // bloco se nenhum case corresponder (opcional)
}
Restrições do switch em C:
#include <stdio.h>

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

    switch (grade) {
        case 'A':
            printf("Grade: A\n");
            break;
        case 'B':
            printf("Grade: B\n");   // este executa
            break;
        case 'C':
            printf("Grade: C\n");
            break;
        default:
            printf("Grade not recognized.\n");
    }

    return 0;
}

Grade: B

O papel do break

O break encerra a execução do switch após o caso correspondente. Sem o break, o código continua executando os casos seguintes — comportamento chamado de fall-through:

#include <stdio.h>

int main() {
    int x = 2;

    switch (x) {
        case 1:
            printf("caso 1\n");
        case 2:
            printf("caso 2\n");   // começa aqui...
        case 3:
            printf("caso 3\n");   // ...e continua (sem break!)
        default:
            printf("default\n");  // ...até aqui
    }

    return 0;
}

caso 2

caso 3

default

Fall-through — quase sempre um bug: Esquecer o break é um dos erros mais comuns com switch. O compilador não avisa sobre fall-through por padrão — ele é tecnicamente válido e até útil em situações específicas (ver abaixo). Sempre adicione break ao final de cada case, a não ser que o fall-through seja intencional e comentado.

Fall-through intencional — agrupando casos

O fall-through pode ser usado de forma controlada para fazer com que múltiplos casos executem o mesmo código:

#include <stdio.h>

int main() {
    int mes = 4;   // abril

    switch (mes) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            printf("Mês com 31 dias.\n");
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            printf("Mês com 30 dias.\n");   // este executa (abril = 4)
            break;
        case 2:
            printf("Fevereiro: 28 ou 29 dias.\n");
            break;
        default:
            printf("Mês inválido.\n");
    }

    return 0;
}

Mês com 30 dias.

Operador Ternário: ?:

O operador ternário é a forma mais compacta de escrever uma decisão condicional em C. Ele avalia uma condição e retorna um de dois valores — tudo em uma única expressão.

condição ? valor_se_verdadeiro : valor_se_falso

É chamado "ternário" porque envolve três operandos: a condição, o valor para verdadeiro e o valor para falso. É o único operador de três operandos em C.
#include <stdio.h>

int main() {
    int age = 20;

    // Forma equivalente com if-else:
    // if (age >= 18) status = "Adult"; else status = "Minor";

    const char* status = (age >= 18) ? "Adult" : "Minor";
    printf("Status: %s\n", status);   // Adult

    // Ternário diretamente no printf
    int numero = -7;
    printf("%d é %s\n", numero, (numero >= 0) ? "positivo" : "negativo");

    // Encontrando o maior entre dois valores
    int a = 15, b = 23;
    int maior = (a > b) ? a : b;
    printf("Maior: %d\n", maior);   // 23

    // Valor absoluto
    int x = -42;
    int abs_x = (x >= 0) ? x : -x;
    printf("|%d| = %d\n", x, abs_x);  // |-42| = 42

    return 0;
}

Status: Adult

-7 é negativo

Maior: 23

|-42| = 42

Quando usar o ternário: Use-o para expressões simples e curtas onde a intenção fica clara à primeira vista. Para decisões com múltiplas instruções ou lógica mais complexa, prefira o if-else completo — legibilidade é mais importante que concisão.
Ternários aninhados — evite: É tecnicamente possível aninhar ternários, mas o resultado é quase sempre ilegível:
// Difícil de ler — evite
int sinal = (x > 0) ? 1 : (x < 0) ? -1 : 0;

// Preferível — use if-else if
int sinal;
if      (x > 0) sinal =  1;
else if (x < 0) sinal = -1;
else            sinal =  0;

Exemplo Completo do Material de Referência

O programa abaixo reúne todos os tipos de estrutura condicional estudados nesta aula e na anterior, diretamente da seção 5 do livro de referência do curso:

#include <stdio.h>

int main() {
    int age = 25;
    char grade = 'B';
    int isStudent = 1;

    // Operador ternário
    const char* status = (age >= 18) ? "Adult" : "Minor";
    printf("Status: %s\n", status);

    // if simples
    if (isStudent) {
        printf("You are a student.\n");
    }

    // if-else
    if (age < 18) {
        printf("Underage.\n");
    } else {
        printf("Of legal age.\n");
    }

    // if-else if-else
    if (grade == 'A') {
        printf("Excellent!\n");
    } else if (grade == 'B') {
        printf("Good job.\n");
    } else {
        printf("Needs improvement.\n");
    }

    // switch-case
    switch (grade) {
        case 'A':
            printf("Grade: A\n");
            break;
        case 'B':
            printf("Grade: B\n");
            break;
        case 'C':
            printf("Grade: C\n");
            break;
        default:
            printf("Grade not recognized.\n");
    }

    return 0;
}

Status: Adult

You are a student.

Of legal age.

Good job.

Grade: B

Quando Usar Cada Estrutura?

Estrutura Use quando... Evite quando...
if Há uma única condição a verificar e um bloco opcional a executar Há muitos caminhos — fica longo e difícil de ler
if-else Há exatamente dois caminhos (verdadeiro ou falso) Há mais de dois caminhos — prefira else-if
else-if Há múltiplas condições booleanas a verificar em sequência As condições comparam um valor com constantes fixas — prefira switch
switch-case Uma variável inteira ou char é comparada com vários valores fixos Há condições de faixa (>, <=) ou valores float/string
Ternário ?: A lógica é simples, cabe em uma linha e o resultado é um valor A lógica é complexa ou há múltiplas instruções para executar

Estruturas Condicionais em C versus Java

Aspecto C Java
else-if Idêntico Idêntico
Operador ternário ?: Idêntico Idêntico
switch — tipos aceitos int, char, short, long, enum Idem + String (desde Java 7) e enum
switch com String Não suportado — use else-if com strcmp() Suportado desde Java 7
Fall-through sem break Ocorre silenciosamente — sem aviso do compilador Ocorre silenciosamente — mesma regra
Múltiplos valores por case Agrupando cases vazios (fall-through intencional) Idem em Java clássico; case 1, 2, 3 -> em Java 14+
Condição do if Qualquer inteiro (0 = falso, não-zero = verdadeiro) Deve ser boolean explícito
switch com retorno direto (arrow) Não disponível em C case X -> valor; disponível em Java 14+

Equivalente de switch com String em C

Como C não aceita strings no switch, a comparação de texto deve ser feita com strcmp() (de <string.h>) numa cadeia else-if:

C — usando else-if + strcmp Java — switch com String
#include <string.h>

char cor[] = "azul";

if (strcmp(cor, "vermelho") == 0)
    printf("Para!\n");
else if (strcmp(cor, "amarelo") == 0)
    printf("Atenção!\n");
else if (strcmp(cor, "azul") == 0)
    printf("Seguro!\n");
else
    printf("Cor desconhecida.\n");
String cor = "azul";

switch (cor) {
    case "vermelho":
        System.out.println("Para!");
        break;
    case "amarelo":
        System.out.println("Atenção!");
        break;
    case "azul":
        System.out.println("Seguro!");
        break;
    default:
        System.out.println("Cor desconhecida.");
}

Exercícios — Aula 09

Teste seus conhecimentos sobre else-if, switch-case e operador ternário:

1. Dado float nota = 85.0, qual será a saída da cadeia else-if abaixo?

if (nota >= 60)
    printf("D\n");
else if (nota >= 70)
    printf("C\n");
else if (nota >= 80)
    printf("B\n");
else if (nota >= 90)
    printf("A\n");

2. O que acontece quando o break é omitido em um case do switch?

3. Qual a saída do código abaixo?

int x = 2;
switch (x) {
    case 1: printf("um\n");
    case 2: printf("dois\n");
    case 3: printf("tres\n"); break;
    default: printf("outro\n");
}

4. Qual será o valor de resultado após executar o código abaixo?

int a = 10, b = 3;
int resultado = (a > b) ? a - b : b - a;

5. Qual tipo de dado não pode ser usado na expressão de um switch em C?

6. Na cadeia else-if, o que acontece quando uma condição verdadeira é encontrada?

7. Qual é a grande vantagem do switch em relação ao else-if quando se compara um valor com muitas constantes?

8. Como comparar strings em uma estrutura de decisão em C, já que o switch não aceita strings?