Exercícios de desvio condicional (if e switch) em C

Reunimos 12 exercícios, do iniciante ao avançado, de desvio condicional com if e switch. Escreva seu código no navegador e clique em "Corrigir": ele é executado com gcc de verdade em várias entradas e a saída é verificada.

Como usar estes exercícios
  1. Leia o enunciado e o exemplo de execução e escreva seu código no campo abaixo
  2. Clique em "▶ Executar" para testar com a sua própria entrada
  3. Clique em "✔ Corrigir" para verificar a saída com várias entradas preparadas
  4. Travou? Abra a "Dica". Resolveu? Compare com "Solução e explicação"
Regras da correção
  • Imprima a saída exatamente como no exemplo. Não imprima mensagens pedindo a entrada, como "Digite um número"
  • Espaços no fim das linhas e linhas em branco no final são ignorados
  • Seu código é salvo automaticamente neste navegador

Obs.: Executar e Corrigir enviam seu código ao Wandbox, um serviço externo e gratuito de compilação, que o executa com gcc.

12 exercícios (Iniciante 4 · Intermediário 5 · Avançado 3)

if e switch (12 exercícios)

I01 Iniciante

Exercício 1. Positivo, negativo ou zero

Leia um inteiro N (−10000 ≤ N ≤ 10000) e mostre "Positivo" se for positivo, "Negativo" se for negativo e "Zero" se for 0.
Exemplo de execução (a entrada está sublinhada)
-3 Negativo
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Como são 3 casos, use if … else if … else. Teste n > 0 e depois n < 0; se não for nenhum dos dois, é 0.
#include <stdio.h>

int main(void) {
    int n;
    scanf("%d", &n);

    if (n > 0) {
        printf("Positivo\n");
    } else if (n < 0) {
        printf("Negativo\n");
    } else {
        printf("Zero\n");
    }
    return 0;
}
Explicação: Três if independentes também funcionariam, mas ligando-os com else if fica claro que apenas um deles é executado. Se você escrever a comparação com 0 como if (n = 0), isso vira uma atribuição: n passa a valer 0 e a condição é sempre falsa. Cuidado (a comparação é ==).
I02 Iniciante

Exercício 2. Par ou ímpar

Leia um inteiro N (−10000 ≤ N ≤ 10000) e mostre "N é par" se for par ou "N é ímpar" se for ímpar (no lugar de N vai o valor lido). Atenção: números negativos também podem ser lidos.
Exemplo de execução (a entrada está sublinhada)
7 7 é ímpar
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Se o resto da divisão por 2, n % 2, for 0, o número é par. Se você testar ímpar com n % 2 == 1, não funciona com números negativos.
#include <stdio.h>

int main(void) {
    int n;
    scanf("%d", &n);

    if (n % 2 == 0) {
        printf("%d é par\n", n);
    } else {
        printf("%d é ímpar\n", n);
    }
    return 0;
}
Explicação: Em C, quando o dividendo é negativo, o resto de % também é negativo: −3 % 2 é −1. Por isso, testando ímpar com if (n % 2 == 1), o −3 seria considerado "par". Testando "se é 0 ou não", funciona corretamente independentemente do sinal.
I03 Iniciante

Exercício 3. O maior de dois números

Leia dois inteiros a e b separados por espaço e mostre o maior no formato "Maior: valor". Se os dois forem iguais, mostre "Valores iguais".
Exemplo de execução (a entrada está sublinhada)
3 7 Maior: 7
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Fica simples se você testar a == b primeiro, tratando o caso de igualdade antes, e separar o resto com a > b.
#include <stdio.h>

int main(void) {
    int a, b;
    scanf("%d %d", &a, &b);

    if (a == b) {
        printf("Valores iguais\n");
    } else if (a > b) {
        printf("Maior: %d\n", a);
    } else {
        printf("Maior: %d\n", b);
    }
    return 0;
}
Explicação: Com apenas dois ramos, if (a > b) … else …, quando os valores são iguais o programa entra no else e mostra "Maior: 5". Em qual lado entra o caso de igualdade (o limite) é algo a ser pensado em todo desvio condicional.
I04 Iniciante

Exercício 4. Verificar se a nota está no intervalo

Leia um inteiro x e mostre "Nota válida" se estiver entre 0 e 100 (inclusive) ou "Fora do intervalo" caso contrário.
Exemplo de execução (a entrada está sublinhada)
101 Fora do intervalo
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
É "maior ou igual a 0 e menor ou igual a 100", então ligue as duas comparações com o E lógico &&. Não dá para escrever 0 <= n <= 100.
#include <stdio.h>

int main(void) {
    int n;
    scanf("%d", &n);

    if (n >= 0 && n <= 100) {
        printf("Nota válida\n");
    } else {
        printf("Fora do intervalo\n");
    }
    return 0;
}
Explicação: 0 <= n <= 100 é interpretado como (0 <= n) <= 100. O resultado de 0 <= n é 0 ou 1, e comparar isso com 100 é sempre verdadeiro; assim 101 e −1 também seriam "válidos" (alguns compiladores mostram um aviso). Escreva intervalos sempre com &&.
I05 Intermediário

Exercício 5. Conceito da nota

Leia uma nota (inteiro de 0 a 100) e mostre, no formato "Conceito: S", S se for 90 ou mais, A se for 80 ou mais, B se for 70 ou mais, C se for 60 ou mais e D se for menor que 60.
Exemplo de execução (a entrada está sublinhada)
85 Conceito: A
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Se você colocar em ordem, da nota mais alta para a mais baixa, if (n >= 90) … else if (n >= 80) …, não precisa escrever duas condições como "80 ou mais e menor que 90".
#include <stdio.h>

int main(void) {
    int n;
    scanf("%d", &n);

    char grade;
    if (n >= 90) {
        grade = 'S';
    } else if (n >= 80) {
        grade = 'A';
    } else if (n >= 70) {
        grade = 'B';
    } else if (n >= 60) {
        grade = 'C';
    } else {
        grade = 'D';
    }
    printf("Conceito: %c\n", grade);
    return 0;
}
Explicação: O else if testa de cima para baixo e executa só o primeiro que for verdadeiro. Ao chegar em else if (n >= 80), já se sabe que é "menor que 90", então não é preciso acrescentar n < 90. Por outro lado, se n >= 60 vier primeiro, até 100 pontos daria C. Os testes com exatamente 90 e 60 nos limites verificam se você trocou > por >=.
I06 Intermediário

Exercício 6. Maior e menor de três números

Leia três inteiros a, b e c separados por espaço e mostre o maior e o menor valor.
Exemplo de execução (a entrada está sublinhada)
3 9 2 Maior: 9 Menor: 2
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Coloque primeiro a na variável max; se b for maior, substitua; se c for maior, substitua… Comparando um por um assim, você não precisa pensar em combinações.
#include <stdio.h>

int main(void) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);

    int max = a, min = a;
    if (b > max) max = b;
    if (c > max) max = c;
    if (b < min) min = b;
    if (c < min) min = c;

    printf("Maior: %d\n", max);
    printf("Menor: %d\n", min);
    return 0;
}
Explicação: O ponto aqui é colocar ifs independentes em sequência, sem else (porque queremos sempre examinar tanto b quanto c). Escrevendo com combinações, como if (a > b && a > c), é fácil errar quando há valores iguais, como em 7 7 1, em que nenhuma condição é satisfeita. Se o valor inicial do máximo for 0, quando todos forem negativos aparece 0.
I07 Intermediário

Exercício 7. Ano bissexto

Leia um ano Y (1 ≤ Y ≤ 9999) e mostre "Y é bissexto" se for bissexto ou "Y não é bissexto" caso contrário. Um ano é bissexto se "for divisível por 4, exceto os divisíveis por 100, mas os divisíveis por 400 são bissextos".
Exemplo de execução (a entrada está sublinhada)
2024 2024 é bissexto
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Juntando a regra em uma única expressão com operadores lógicos: "(divisível por 4 e não divisível por 100) ou divisível por 400". Ao misturar && e ||, use parênteses.
#include <stdio.h>
#include <stdbool.h>

int main(void) {
    int y;
    scanf("%d", &y);

    bool leap = (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;

    if (leap) {
        printf("%d é bissexto\n", y);
    } else {
        printf("%d não é bissexto\n", y);
    }
    return 0;
}
Explicação: Só "divisível por 4 é bissexto" erra 1900 e 2100. Guardando o resultado da condição em uma variável bool (<stdbool.h>), você pode escrever de forma legível: if (leap). Como && tem precedência maior que ||, o significado é o mesmo sem parênteses, mas é recomendável usar parênteses para quem vai ler o código.
I08 Intermediário

Exercício 8. Dias do mês (switch)

Leia um mês M como inteiro e mostre o número de dias desse mês em um ano comum (fevereiro com 28 dias) no formato "O mês M tem 30 dias". Se M não estiver entre 1 e 12, mostre "Mês inválido". Use a instrução switch.
Exemplo de execução (a entrada está sublinhada)
4 O mês 4 tem 30 dias
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Meses com o mesmo número de dias podem ser agrupados colocando os case em sequência, como case 4: case 6: case 9: case 11:. Valores fora de 1 a 12 são tratados no default.
#include <stdio.h>

int main(void) {
    int m;
    scanf("%d", &m);

    int days;
    switch (m) {
    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:
        printf("Mês inválido\n");
        return 0;
    }
    printf("O mês %d tem %d dias\n", m, days);
    return 0;
}
Explicação: O switch executa em sequência as instruções a partir do case correspondente até o break. Usando essa característica, você pode enfileirar cases sem instruções para dizer "se for qualquer um destes, faça o mesmo". Por outro lado, se esquecer o break, depois do mês 4 o processamento continua também no case seguinte. Cuidado.
I09 Intermediário

Exercício 9. Pedra, papel e tesoura

Leia as jogadas de A e B como inteiros separados por espaço (0: pedra, 1: tesoura, 2: papel). Na 1ª linha mostre as duas jogadas, como "A: Pedra B: Tesoura", e na 2ª linha mostre "A venceu", "B venceu" ou "Empate".
Exemplo de execução (a entrada está sublinhada)
0 1 A: Pedra B: Tesoura A venceu
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
O nome da jogada pode ser mostrado com um switch. Para o resultado, você pode escrever todos os 9 casos, mas calculando (a - b + 3) % 3, 0 é empate, 2 é vitória de A e 1 é vitória de B.
#include <stdio.h>

void print_hand(int h) {
    switch (h) {
    case 0: printf("Pedra"); break;
    case 1: printf("Tesoura"); break;
    case 2: printf("Papel"); break;
    }
}

int main(void) {
    int a, b;
    scanf("%d %d", &a, &b);

    printf("A: ");
    print_hand(a);
    printf(" B: ");
    print_hand(b);
    printf("\n");

    int r = (a - b + 3) % 3;
    if (r == 0) {
        printf("Empate\n");
    } else if (r == 2) {
        printf("A venceu\n");
    } else {
        printf("B venceu\n");
    }
    return 0;
}
Explicação: A ordem pedra(0)→tesoura(1)→papel(2)→pedra faz com que cada jogada vença a de número 1 maior, então o resultado é decidido pelo resto da divisão da diferença a − b por 3. Se você esquecer o + 3, quando a − b for negativo o resto também será negativo (por exemplo, −1 % 3 é −1) e o resultado sai errado. Se você ainda não aprendeu funções, pode escrever o switch duas vezes dentro do main.
I10 Avançado

Exercício 10. Calculadora simples

Leia uma expressão no formato "inteiro operador inteiro" (por exemplo, 7 / 2) e mostre o resultado no formato "7 / 2 = 3". Os operadores são os 5 tipos + - * / %, sendo / e % a divisão inteira e o resto de C. Se o operador for / ou % e o lado direito for 0, mostre "Erro: divisão por zero"; para qualquer outro operador, mostre "Erro: operador desconhecido" (os inteiros vão de −10000 a 10000).
Exemplo de execução (a entrada está sublinhada)
7 / 2 7 / 2 = 3
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Faça o desvio com switch (op) pelo caractere do operador e compare com constantes de caractere, como case '+':. Dentro dos cases de / e %, teste b == 0 primeiro.
#include <stdio.h>

int main(void) {
    int a, b;
    char op;
    scanf("%d %c %d", &a, &op, &b);

    int result;
    switch (op) {
    case '+':
        result = a + b;
        break;
    case '-':
        result = a - b;
        break;
    case '*':
        result = a * b;
        break;
    case '/':
    case '%':
        if (b == 0) {
            printf("Erro: divisão por zero\n");
            return 0;
        }
        result = (op == '/') ? a / b : a % b;
        break;
    default:
        printf("Erro: operador desconhecido\n");
        return 0;
    }
    printf("%d %c %d = %d\n", a, op, b, result);
    return 0;
}
Explicação: Dividir por 0 é comportamento indefinido e pode até encerrar o programa de forma anormal, por isso a verificação é feita antes de dividir. Colocar um espaço antes de %c no scanf, " %c" (aqui, "%d %c %d"), indica que os espaços anteriores devem ser pulados antes de ler 1 caractere. Sem o espaço, o espaço depois do número iria parar em op.
I11 Avançado

Exercício 11. Classificar triângulos

Leia os comprimentos dos 3 lados a, b e c (inteiros de 1 a 1000, em qualquer ordem). Se não for possível formar um triângulo, mostre "Não é um triângulo". Se for possível, mostre "Triângulo equilátero" se for equilátero, "Triângulo isósceles" se for isósceles, "Triângulo retângulo" se for retângulo e "Triângulo comum" se não for nenhum desses. Para o equilátero, mostre apenas "Triângulo equilátero". A condição para formar um triângulo é que "a soma de quaisquer dois lados seja maior que o terceiro lado".
Exemplo de execução (a entrada está sublinhada)
5 3 4 Triângulo retângulo
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
A ordem dos testes é importante. Ligue com else if nesta ordem: ① forma um triângulo? → ② os 3 lados são iguais? → ③ dois lados são iguais? → ④ é retângulo? Como a ordem dos lados não é fixa, para o retângulo ligue as 3 versões de a*a + b*b == c*c com ||.
#include <stdio.h>

int main(void) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);

    if (a + b <= c || b + c <= a || c + a <= b) {
        printf("Não é um triângulo\n");
    } else if (a == b && b == c) {
        printf("Triângulo equilátero\n");
    } else if (a == b || b == c || c == a) {
        printf("Triângulo isósceles\n");
    } else if (a * a + b * b == c * c || b * b + c * c == a * a || c * c + a * a == b * b) {
        printf("Triângulo retângulo\n");
    } else {
        printf("Triângulo comum\n");
    }
    return 0;
}
Explicação: 2 5 2 tem dois lados iguais, mas como 2 + 2 < 5, não forma um triângulo. Se a verificação de existência não vier primeiro, aparece "isósceles" por engano. Da mesma forma, o equilátero também satisfaz a condição do isósceles, então a condição mais restrita (equilátero) é testada antes. a == b == c significa (a == b) == c, por isso use && (como os lados são inteiros, o triângulo retângulo isósceles não aparece neste exercício).
I12 Avançado

Exercício 12. Qual de duas datas vem antes

Leia duas datas no formato "ano mês dia", uma por linha (ambas são datas que existem), e mostre "A primeira data vem antes" se a primeira for anterior, "A segunda data vem antes" se a segunda for anterior, ou "As datas são iguais" se forem a mesma.
Exemplo de execução (a entrada está sublinhada)
2024 3 15 2024 3 20 A primeira data vem antes
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Compare na ordem ano → mês → dia. "O ano é menor, ou o ano é igual e o mês é menor, ou ano e mês são iguais e o dia é menor" pode ser escrito como uma única condição com || e &&.
#include <stdio.h>

int main(void) {
    int y1, m1, d1, y2, m2, d2;
    scanf("%d %d %d", &y1, &m1, &d1);
    scanf("%d %d %d", &y2, &m2, &d2);

    if (y1 == y2 && m1 == m2 && d1 == d2) {
        printf("As datas são iguais\n");
    } else if (y1 < y2 || (y1 == y2 && m1 < m2) || (y1 == y2 && m1 == m2 && d1 < d2)) {
        printf("A primeira data vem antes\n");
    } else {
        printf("A segunda data vem antes\n");
    }
    return 0;
}
Explicação: Comparando cada campo separadamente, como y1 <= y2 && m1 <= m2 && d1 <= d2, o resultado sai errado para 2023/12/31 e 2024/1/1, porque o mês e o dia da primeira são maiores. Comparar a unidade menor só quando a unidade maior for igual é a comparação lexicográfica. Uma alternativa é transformar cada data em um único inteiro, y * 10000 + m * 100 + d, e comparar.

Revise estas aulas

← Voltar para todos os exercícios