Prática: Exercícios para Iniciantes

Aprender a programar é como aprender a nadar — ler livros não substitui entrar na água. Esta aula une as 9 primeiras lições fazendo você escrever 3 mini-programas completos.

Projeto 1: Conversor de Celsius para Fahrenheit

Este projeto combina variáveis, aritmética e entrada/saída. A fórmula é:

F = C x 9 / 5 + 32

Análise de requisitos

Conceitos-chave

Exemplo

C
#include <stdio.h>

int main(void) {
    double celsius;
    printf("Enter temperature in Celsius: ");
    scanf("%lf", &celsius);

    double fahrenheit = celsius * 9.0 / 5.0 + 32.0;
    double kelvin = celsius + 273.15;

    printf("\n===== Temperature Conversion =====\n");
    printf("Celsius:   %.2f C\n", celsius);
    printf("Fahrenheit:%.2f F\n", fahrenheit);
    printf("Kelvin:    %.2f K\n", kelvin);
    printf("==================================\n");
    return 0;
}
▶ Experimente
TEXT
Enter temperature in Celsius: 36.5

===== Temperature Conversion =====
Celsius:   36.50 C
Fahrenheit:97.70 F
Kelvin:    309.65 K
==================================
💡 Dica: Escreva 9.0 / 5.0 em vez de 9 / 5, porque a divisão inteira 9/5 resulta em 1, não 1.8, o que produziria resultados incorretos.

Erros comuns

  1. Divisão inteira: celsius * 9 / 5 trunca 9/5 para 1 -> escreva 9.0/5.0
  2. Usar %f no scanf para double: double deve usar %lf; printf pode usar %f para double
  3. Esquecer &: scanf("%lf", celsius) vai causar falha -> scanf("%lf", &celsius)

Desafio extra

Você consegue fazer a conversão inversa — inserir Fahrenheit e obter Celsius? A fórmula é C = (F - 32) x 5 / 9.

Projeto 2: Verificador de Ano Bissexto

Este projeto combina condicionais, operadores lógicos e o operador módulo.

Regras do ano bissexto

Expresso como condição lógica:

C
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)

Análise de requisitos

Conceitos-chave

Exemplo

C
#include <stdio.h>

int main(void) {
    int year;
    printf("Enter a year: ");
    scanf("%d", &year);

    if (year <= 0) {
        printf("Error: Year must be a positive integer\n");
        return 1;
    }

    int is_leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    int feb_days = is_leap ? 29 : 28;

    printf("\n===== Result =====\n");
    printf("Year:     %d\n", year);
    printf("Type:     %s\n", is_leap ? "Leap year" : "Common year");
    printf("Feb days: %d\n", feb_days);
    printf("==================\n");
    return 0;
}
▶ Experimente
TEXT
Enter a year: 2000

===== Result =====
Year:     2000
Type:     Leap year
Feb days: 29
==================

Teste alguns anos limite:

Ano Resultado esperado Motivo
2000 Ano bissexto Divisível por 400
1900 Ano comum Divisível por 100 mas não por 400
2024 Ano bissexto Divisível por 4 mas não por 100
2023 Ano comum Não divisível por 4

Derivação passo a passo

Iniciantes frequentemente erram a condição de ano bissexto. Vamos derivá-la passo a passo:

  1. Primeiro passo: divisível por 4 -> provavelmente é bissexto
  2. Segundo passo: mas anos seculares divisíveis por 100 geralmente não são bissextos -> adicionar condição "e não divisível por 100"
  3. Terceiro passo: mas anos seculares divisíveis por 400 são bissextos -> adicionar condição "ou divisível por 400"
💡 Dica: Derivar passo a passo é mais confiável do que memorizar uma fórmula. Para condições complexas, escreva uma versão simples primeiro, depois adicione correções incrementalmente.

Projeto 3: Calculadora Simples

Este projeto combina switch-case, laços, entrada/saída e operações aritméticas.

Análise de requisitos

Conceitos-chave

Exemplo

C
#include <stdio.h>

int main(void) {
    double a, b;
    char op;
    char again;

    do {
        printf("\n===== Simple Calculator =====\n");
        printf("Enter expression (e.g. 3 + 5): ");
        scanf("%lf %c %lf", &a, &op, &b);

        printf("--------------------\n");
        switch (op) {
            case '+':
                printf("%.2f + %.2f = %.2f\n", a, b, a + b);
                break;
            case '-':
                printf("%.2f - %.2f = %.2f\n", a, b, a - b);
                break;
            case '*':
                printf("%.2f * %.2f = %.2f\n", a, b, a * b);
                break;
            case '/':
                if (b == 0) {
                    printf("Error: Division by zero!\n");
                } else {
                    printf("%.2f / %.2f = %.2f\n", a, b, a / b);
                }
                break;
            default:
                printf("Error: Unsupported operator '%c'\n", op);
                break;
        }
        printf("--------------------\n");

        printf("Continue? (Y/N): ");
        scanf(" %c", &again);
    } while (again == 'Y' || again == 'y');

    printf("Goodbye!\n");
    return 0;
}
▶ Experimente
TEXT
===== Simple Calculator =====
Enter expression (e.g. 3 + 5): 10 / 3
--------------------
10.00 / 3.00 = 3.33
--------------------
Continue? (Y/N): Y

===== Simple Calculator =====
Enter expression (e.g. 3 + 5): 5 / 0
--------------------
Error: Division by zero!
--------------------
Continue? (Y/N): N
Goodbye!

Destaques de design

  1. Formato de entrada: scanf("%lf %c %lf", &a, &op, &b) lê três valores em uma chamada, separados por espaços — conciso e natural
  2. Proteção contra divisão por zero: No case '/', verifica b == 0 primeiro para evitar erro em tempo de execução
  3. Controle de laço: do-while garante pelo menos um cálculo; o usuário escolhe se deseja continuar
  4. Tratamento de buffer: O espaço antes de %c em scanf(" %c", &again) ignora a quebra de linha residual da entrada anterior

Desafio extra

Adicione o operador módulo % à calculadora (note que os operandos devem ser inteiros), e uma dica para exponenciação (usando a função pow de math.h).

Revisão abrangente de conhecimento

Esses 3 projetos cobrem o conhecimento central das primeiras 9 aulas:

Projeto Conceitos abordados
Conversão de temperatura Variáveis e tipos, aritmética, formatação printf, entrada scanf, armadilha da divisão inteira
Verificador de ano bissexto Módulo, operadores relacionais, operadores lógicos, if-else, operador ternário, validação de entrada
Calculadora simples switch-case, laço do-while, continue, tratamento de buffer, verificação de divisão por zero

Passos gerais para escrever bons programas

  1. Entenda os requisitos: Qual é a entrada? Qual é a saída? Quais são os casos extremos?
  2. Escolha as estruturas: Quais comandos usar? if ou switch? for ou while?
  3. Escreva pseudocódigo: Descreva a lógica em linguagem natural primeiro, depois traduza para C
  4. Implemente incrementalmente: Escreva e teste aos poucos; não escreva tudo de uma vez antes de depurar
  5. Teste minuciosamente: Teste valores normais, valores limite e valores inválidos

❓ Perguntas Frequentes

P: Por que scanf precisa de %lf para double mas printf usa %f? R: scanf precisa saber o tamanho exato do parâmetro para escrever na memória corretamente; double e float têm tamanhos diferentes. Em printf, float é automaticamente promovido a double, então %f funciona para ambos.

P: É melhor uma única expressão lógica ou if aninhado para verificar ano bissexto? R: Uma expressão lógica é mais compacta para condições simples; if aninhado é mais legível para condições complexas. Iniciantes devem começar com if aninhado para entender a lógica, depois simplificar para uma expressão lógica.

P: Comparar b == 0 para um número de ponto flutuante é confiável? R: Estritamente falando, números de ponto flutuante não devem ser comparados com ==, mas quando o usuário insere diretamente 0, ele é exatamente 0.0. Uma abordagem mais rigorosa é fabs(b) < 1e-10, que requer math.h.

P: E se meu programa já estiver errado pela metade? Como depurar? R: Adicione comandos printf em pontos-chave para exibir valores intermediários das variáveis e reduza gradualmente o erro. Isso é chamado de "depuração com printf" — a técnica de depuração mais básica e eficaz.

📖 Resumo

📝 Exercícios

  1. Adicione um recurso de conversão inversa ao programa de temperatura: digite 1 para Celsius para Fahrenheit, 2 para Fahrenheit para Celsius, usando switch ou if-else.
  2. Aprimore o programa de ano bissexto para aceitar um ano inicial e final, depois exibir todos os anos bissextos nesse intervalo (usando um laço for).
  3. Adicione módulo % e divisão inteira à calculadora. Note que módulo requer operandos inteiros, então solicite ao usuário que insira inteiros.
100%