Condicionais

Condicionais são como semáforos em um cruzamento — quando a condição é atendida, você segue por um caminho; caso contrário, por outro. Programas ganham inteligência através da tomada de decisões.

O comando if

if é o condicional mais fundamental. Quando a condição é verdadeira (não zero), o código dentro das chaves é executado; quando falsa (zero), é ignorado.

C
#include <stdio.h>

int main(void) {
    int score = 95;
    if (score >= 90) {
        printf("Excellent!\n");
    }
    printf("Program continues\n");
    return 0;
}
TEXT
Excellent!
Program continues
💡 Dica: Se há apenas um comando após o if, as chaves podem ser omitidas. No entanto, é altamente recomendável sempre usar chaves para evitar erros de lógica ao adicionar comandos depois e esquecer de incluir as chaves.

O comando if-else

if-else oferece dois ramos: se a condição é verdadeira, o bloco if executa; se falsa, o bloco else executa. Um dos dois sempre será executado.

C
#include <stdio.h>

int main(void) {
    int age = 16;
    if (age >= 18) {
        printf("You are an adult\n");
    } else {
        printf("You are a minor\n");
    }
    return 0;
}
TEXT
You are a minor

O problema do else pendente

Quando múltiplos if estão aninhados, o else se emparelha com o if mais próximo:

C
#include <stdio.h>

int main(void) {
    int a = 5, b = 0;
    if (a > 10)
        if (b > 0)
            printf("A\n");
    else
        printf("B\n");
    return 0;
}

Parece que o else se emparelha com o primeiro if, mas na verdade se emparelha com o segundo if, então nada é impresso. Adicionar chaves deixa o emparelhamento claro:

C
if (a > 10) {
    if (b > 0) {
        printf("A\n");
    } else {
        printf("B\n");
    }
}
⚠️ Atenção: Sempre usar chaves elimina completamente o problema do else pendente.

A cadeia if-else if-else

Quando múltiplas condições precisam ser verificadas em sequência, use else if para encadear vários ramos:

C
#include <stdio.h>

int main(void) {
    int score = 78;
    if (score >= 90) {
        printf("Grade: A\n");
    } else if (score >= 80) {
        printf("Grade: B\n");
    } else if (score >= 70) {
        printf("Grade: C\n");
    } else if (score >= 60) {
        printf("Grade: D\n");
    } else {
        printf("Grade: F\n");
    }
    return 0;
}
TEXT
Grade: C

As condições do else if são avaliadas de cima para baixo. Uma vez que uma condição é satisfeita, todos os ramos subsequentes são ignorados. A ordem das condições importa.

💡 Dica: Coloque as condições mais prováveis primeiro para maior eficiência; organize os intervalos do maior para o menor para evitar lacunas na lógica.

Condicionais aninhados

Um if pode ser aninhado dentro de outro if para uma lógica condicional mais refinada:

C
#include <stdio.h>

int main(void) {
    int age = 25;
    char gender = 'M';
    if (age >= 18) {
        if (gender == 'M') {
            printf("Adult male\n");
        } else {
            printf("Adult female\n");
        }
    } else {
        printf("Minor\n");
    }
    return 0;
}
TEXT
Adult male
⚠️ Atenção: O aninhamento não deve ultrapassar 3 níveis. Níveis demais prejudicam a legibilidade. Condições complexas podem ser combinadas com operadores lógicos ou simplificadas com else if.

O comando switch-case

switch salta para o ramo case correspondente com base no valor de uma expressão inteira. É ideal para ramificações em valores discretos.

Sintaxe básica

C
switch (expression) {
    case constant1:
        statement;
        break;
    case constant2:
        statement;
        break;
    default:
        statement;
        break;
}
C
#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("Invalid day\n"); break;
    }
    return 0;
}
TEXT
Wednesday

A importância do break

Após o switch encontrar um case correspondente, ele executa todos os comandos a partir daquele ponto até encontrar um break ou o fim do switch. Isso é chamado de "fall-through" (queda).

C
#include <stdio.h>

int main(void) {
    int num = 2;
    switch (num) {
        case 1: printf("One\n");
        case 2: printf("Two\n");
        case 3: printf("Three\n");
        default: printf("Default\n");
    }
    return 0;
}
TEXT
Two
Three
Default
⚠️ Atenção: Esquecer o break é o erro mais comum em switch. A menos que esteja usando fall-through intencionalmente, sempre adicione break ao final de cada case.

Usando fall-through para mesclar ramos

Às vezes, múltiplos rótulos case precisam executar a mesma lógica. Você pode omitir o break deliberadamente:

C
#include <stdio.h>

int main(void) {
    char grade = 'B';
    switch (grade) {
        case 'A':
        case 'B':
        case 'C':
            printf("Pass\n"); break;
        case 'D':
            printf("Retake\n"); break;
        case 'F':
            printf("Fail\n"); break;
        default:
            printf("Invalid grade\n"); break;
    }
    return 0;
}
TEXT
Pass

Limitações do switch

O operador condicional (ternário)

O operador condicional ?: pode substituir comandos if-else simples. Ele foi introduzido na aula 6; aqui estão mais exemplos de uso:

C
#include <stdio.h>

int main(void) {
    int a = -5;
    int abs_a = a >= 0 ? a : -a;
    printf("|%d| = %d\n", a, abs_a);

    int x = 10, y = 10;
    printf("%s\n", x == y ? "Equal" : "Not equal");
    return 0;
}
TEXT
|-5| = 5
Equal
💡 Dica: O operador condicional pode ser aninhado, mas a legibilidade cai rapidamente. Se o aninhamento ultrapassar um nível, use if-else.

Exemplo

Determine o tipo corporal com base no IMC, demonstrando lógica condicional de múltiplos ramos:

C
#include <stdio.h>

int main(void) {
    double weight = 70.0;
    double height = 1.75;
    double bmi = weight / (height * height);

    printf("BMI: %.1f\n", bmi);
    if (bmi < 18.5) {
        printf("Underweight\n");
    } else if (bmi < 24.0) {
        printf("Normal\n");
    } else if (bmi < 28.0) {
        printf("Overweight\n");
    } else {
        printf("Obese\n");
    }
    return 0;
}
▶ Experimente
TEXT
BMI: 22.9
Normal

Exemplo

Implemente uma seleção de menu simples usando switch:

C
#include <stdio.h>

int main(void) {
    int choice = 2;
    printf("===== Menu =====\n");
    printf("1. New Game\n");
    printf("2. Continue\n");
    printf("3. Settings\n");
    printf("4. Exit\n");
    printf("================\n");
    printf("Your choice: %d\n", choice);

    switch (choice) {
        case 1: printf("Starting new game!\n"); break;
        case 2: printf("Loading save...\n"); break;
        case 3: printf("Opening settings\n"); break;
        case 4: printf("Exiting game\n"); break;
        default: printf("Invalid choice\n"); break;
    }
    return 0;
}
▶ Experimente
TEXT
===== Menu =====
1. New Game
2. Continue
3. Settings
4. Exit
================
Your choice: 2
Loading save...

❓ Perguntas Frequentes

P: Quando as chaves podem ser omitidas após o if? R: Sintaticamente, as chaves podem ser omitidas quando há apenas um comando após o if/else, mas é recomendável sempre usá-las para evitar bugs ao esquecer de adicioná-las quando mais comandos forem inseridos.

P: O switch pode avaliar números de ponto flutuante ou strings? R: Não. O switch só aceita expressões inteiras. Nem números de ponto flutuante nem strings funcionam. Para comparar strings, use uma cadeia if-else if.

P: O ramo default pode ser omitido? R: Sintaticamente sim, mas é recomendável mantê-lo para lidar com casos inesperados e evitar erros silenciosos de valores não tratados.

P: Qual a diferença entre else if e if aninhado? R: else if é uma estrutura plana de múltiplos ramos mais fácil de ler; if aninhado é hierárquico e adequado quando as condições dependem umas das outras. Eles são intercambiáveis — escolha o que for mais legível.

📖 Resumo

📝 Exercícios

  1. Escreva um programa que leia um inteiro e determine se é positivo, negativo ou zero, imprimindo o resultado.
  2. Escreva um programa que leia um número de mês (1-12) e use switch para exibir a quantidade de dias daquele mês (considere ano não bissexto, então fevereiro tem 28 dias).
  3. Escreva um programa que leia um caractere e determine se é uma letra maiúscula, uma letra minúscula, um dígito ou outro caractere.
100%