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
- Entrada: temperatura em Celsius (pode ser decimal)
- Saída: temperatura correspondente em Fahrenheit, arredondada para 1 casa decimal
- Extensão: também exibir a temperatura Kelvin (K = C + 273.15)
Conceitos-chave
- Tipo
doublepara armazenar números de ponto flutuante scanf("%lf")para ler um número de ponto flutuante de dupla precisãoprintf("%.1f")para controlar as casas decimais- Precedência de operadores em expressões aritméticas
Exemplo
#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;
}
Enter temperature in Celsius: 36.5
===== Temperature Conversion =====
Celsius: 36.50 C
Fahrenheit:97.70 F
Kelvin: 309.65 K
==================================
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
- Divisão inteira:
celsius * 9 / 5trunca9/5para 1 -> escreva9.0/5.0 - Usar
%fnoscanfparadouble:doubledeve usar%lf;printfpode usar%fparadouble - 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
- Divisível por 4 mas não por 100 -> ano bissexto
- Divisível por 400 -> também é bissexto
- Caso contrário -> ano comum
Expresso como condição lógica:
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
Análise de requisitos
- Entrada: um inteiro positivo representando um ano
- Saída: se o ano é bissexto ou comum, e o número de dias em fevereiro
- Verificação defensiva: tratar entrada inválida (números negativos ou zero)
Conceitos-chave
- Módulo
%para verificar divisibilidade - Operadores lógicos
&&,||para combinar condições - Estrutura de múltiplos ramos
if-else if-else - Validação de entrada
Exemplo
#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;
}
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:
- Primeiro passo: divisível por 4 -> provavelmente é bissexto
- 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"
- Terceiro passo: mas anos seculares divisíveis por 400 são bissextos -> adicionar condição "ou divisível por 400"
Projeto 3: Calculadora Simples
Este projeto combina switch-case, laços, entrada/saída e operações aritméticas.
Análise de requisitos
- Entrada: dois números e um operador (+ - * /)
- Saída: o resultado do cálculo
- Verificação defensiva: exibir mensagem ao dividir por zero
- Laço: perguntar se deseja continuar após cada cálculo
Conceitos-chave
switch-casepara tratar operadoresdo-whilepara cálculos repetidos- Verificação de divisão por zero
- Alinhamento de saída formatada
continuepara ignorar operações inválidas
Exemplo
#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;
}
===== 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
- Formato de entrada:
scanf("%lf %c %lf", &a, &op, &b)lê três valores em uma chamada, separados por espaços — conciso e natural - Proteção contra divisão por zero: No
case '/', verificab == 0primeiro para evitar erro em tempo de execução - Controle de laço:
do-whilegarante pelo menos um cálculo; o usuário escolhe se deseja continuar - Tratamento de buffer: O espaço antes de
%cemscanf(" %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
- Entenda os requisitos: Qual é a entrada? Qual é a saída? Quais são os casos extremos?
- Escolha as estruturas: Quais comandos usar? if ou switch? for ou while?
- Escreva pseudocódigo: Descreva a lógica em linguagem natural primeiro, depois traduza para C
- Implemente incrementalmente: Escreva e teste aos poucos; não escreva tudo de uma vez antes de depurar
- Teste minuciosamente: Teste valores normais, valores limite e valores inválidos
❓ Perguntas Frequentes
P: Por que
scanfprecisa de%lfparadoublemasprintfusa%f? R:scanfprecisa saber o tamanho exato do parâmetro para escrever na memória corretamente;doubleefloattêm tamanhos diferentes. Emprintf,floaté automaticamente promovido adouble, então%ffunciona 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 == 0para 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 requermath.h.
P: E se meu programa já estiver errado pela metade? Como depurar? R: Adicione comandos
printfem 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
- Escrever programas completos é a forma mais rápida de dominar C; apenas ler não vai te levar lá
- A divisão inteira é a armadilha mais comum em aritmética de ponto flutuante — certifique-se de que ao menos um operando seja escrito como decimal
- Derive condições complexas passo a passo: escreva a regra base primeiro, depois adicione correções
- switch-case junto com do-while é o padrão clássico para menus interativos
- Fluxo geral de programação: entender requisitos -> escolher estruturas -> escrever pseudocódigo -> implementar -> testar
📝 Exercícios
- 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.
- 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).
- Adicione módulo
%e divisão inteira à calculadora. Note que módulo requer operandos inteiros, então solicite ao usuário que insira inteiros.



