Semana 02 — Estruturas condicionais¶
Nesta semana
Unidade 1 · Seg 17/08 · Qua 19/08 · Sex 21/08
Até agora nossos programas eram uma linha reta: as instruções rodavam sempre, na mesma ordem, do começo ao fim. Nesta semana o programa ganha a capacidade de tomar decisões — escolher caminhos diferentes conforme os dados. Esse é o salto que separa um "calculador" de um programa que reage ao mundo.
Você vai dominar o if, o else, o encadeamento com else if, o aninhamento de
condições, a combinação de testes com operadores lógicos e a estrutura de múltipla
escolha switch. Como sempre: digite e execute cada exemplo.
🎯 Objetivos de aprendizagem¶
Ao final desta semana, você deverá ser capaz de:
- explicar o que é controle de fluxo e por que decisões são essenciais em programação;
- escrever estruturas
if,if/elsee cadeiaselse ifcorretas e legíveis; - combinar condições com os operadores lógicos
&&,||e!, entendendo a avaliação em curto-circuito; - construir e ler condicionais aninhadas, sabendo quando elas ajudam e quando atrapalham;
- usar a estrutura
switchadequadamente, conhecendo o papel dobreake o fenômeno do fall-through; - reconhecer e evitar os erros clássicos de decisão (
=vs==,;após oif, intervalos mal escritos,breakesquecido).
📖 Segunda — Estudo do conteúdo¶
1. Por que um programa precisa decidir?¶
Muitos problemas do mundo real têm a forma "se… então… senão…":
- Se a nota for maior ou igual a 6, então o aluno está aprovado, senão reprovado.
- Se o saldo for suficiente, então autorize a compra, senão recuse.
- Se o número for par, então faça uma coisa; senão, faça outra.
Em Pensamento Computacional você já desenhou fluxogramas com losangos de decisão. A estrutura condicional é exatamente isso, escrito em C: um teste (uma condição que é verdadeira ou falsa) que determina qual bloco de instruções será executado.
flowchart TD
A["nota >= 6 ?"] -->|verdadeiro| B["imprime<br/>Aprovado"]
A -->|falso| C["imprime<br/>Reprovado"]
B --> D["continua o programa"]
C --> D
2. Relembrando: verdadeiro, falso e comparações¶
Antes de decidir, o programa precisa avaliar uma condição. Como vimos na Semana 01, em C:
- falso é o valor
0; - verdadeiro é qualquer valor diferente de zero (a convenção é
1).
Uma comparação produz esse valor lógico. Recapitulando os operadores relacionais:
| Operador | Significado | Exemplo verdadeiro |
|---|---|---|
== |
igual a | idade == 18 |
!= |
diferente de | resposta != 's' |
< |
menor que | nota < 6 |
> |
maior que | saldo > 0 |
<= |
menor ou igual | nota <= 10 |
>= |
maior ou igual | idade >= 18 |
O erro nº 1 das condicionais: = no lugar de ==
= atribui; == compara. Dentro de um if, trocar um pelo outro muda tudo —
e compila sem erro:
if (idade = 18) { ... } // ERRADO: atribui 18 a idade; a condição vira "18" (verdadeiro SEMPRE)
if (idade == 18) { ... } // certo: pergunta se idade vale 18
idade = 18 resulta em 18 (diferente de zero), o if sempre executa. Bugs
assim são difíceis de achar. Leia sempre suas condições em voz alta: "se idade for
igual a 18".
3. A estrutura if¶
A forma mais simples: execute um bloco apenas se a condição for verdadeira.
Exemplo:
int idade;
scanf("%d", &idade);
if (idade >= 18) {
printf("Voce e maior de idade.\n");
}
printf("Fim.\n"); // esta linha roda SEMPRE (está fora do if)
Se idade for 20, imprime as duas linhas; se for 15, imprime só "Fim.".
O ; fantasma depois do if
Um ponto e vírgula logo após a condição cria um bloco vazio — e o que você achava que era o "corpo do if" passa a rodar sempre:
if (idade >= 18); // <- este ; encerra o if aqui (corpo vazio!)
{
printf("Maior de idade\n"); // roda SEMPRE, independentemente da idade
}
; imediatamente após if (...).
4. if … else: os dois caminhos¶
Quando há uma ação para o caso verdadeiro e outra para o falso:
int nota;
scanf("%d", ¬a);
if (nota >= 6) {
printf("Aprovado\n");
} else {
printf("Reprovado\n");
}
Exatamente um dos dois blocos executa — nunca os dois, nunca nenhum. O else é
sempre opcional e, quando presente, "pertence" ao if mais próximo.
5. Blocos, chaves e legibilidade¶
As chaves { } agrupam várias instruções em um bloco. Se o corpo tem uma única
instrução, o C permite omitir as chaves — mas não faça isso:
// Funciona, porém arriscado:
if (aprovado)
printf("Parabens!\n");
// Recomendado (sempre com chaves):
if (aprovado) {
printf("Parabens!\n");
}
Por que sempre usar chaves? Porque, sem elas, apenas a primeira linha pertence ao
if. Um descuido gera bugs silenciosos:
if (aprovado)
printf("Parabens!\n");
printf("Matricula liberada.\n"); // ENGANO: esta linha roda SEMPRE (não está no if!)
Padronize o recuo (indentação)
O C ignora espaços e quebras de linha, mas humanos não. Recue o conteúdo dos blocos (o Code::Blocks faz isso automaticamente). Código bem indentado revela a estrutura de decisões só de bater o olho — e evita a confusão do exemplo acima.
6. else if: escolhendo entre vários caminhos¶
Quando há mais de duas possibilidades, encadeamos testes com else if:
int nota;
scanf("%d", ¬a);
if (nota >= 90) {
printf("Conceito A\n");
} else if (nota >= 70) {
printf("Conceito B\n");
} else if (nota >= 50) {
printf("Conceito C\n");
} else {
printf("Conceito D\n");
}
As condições são testadas de cima para baixo. A primeira verdadeira executa seu
bloco, e todas as demais são ignoradas. O else final (sem condição) é o "caso
contrário", que pega tudo o que sobrou.
A ordem dos testes importa!
Como o primeiro verdadeiro "vence", condições mais restritivas devem vir antes. Veja o que acontece se invertermos:
if (nota >= 50) { // uma nota 95 já cai AQUI...
printf("Conceito C\n"); // ...e imprime C, errado!
} else if (nota >= 70) {
printf("Conceito B\n");
} else if (nota >= 90) {
printf("Conceito A\n");
}
nota >= 70 && nota < 90 no segundo
teste — se o programa chegou lá, é porque o primeiro if (>= 90) já falhou.
7. Combinando condições com operadores lógicos¶
Muitas decisões dependem de mais de uma condição ao mesmo tempo. Para isso usamos os operadores lógicos, já apresentados na Semana 01:
| Operador | Nome | Resultado verdadeiro quando… |
|---|---|---|
&& |
E (and) | ambas as condições são verdadeiras |
\|\| |
OU (or) | pelo menos uma é verdadeira |
! |
NÃO (not) | inverte o valor lógico |
// Pode entrar no brinquedo? Precisa ter 12+ anos E 1,40m+ de altura.
if (idade >= 12 && altura >= 1.40) {
printf("Pode entrar.\n");
}
// É fim de semana? Sábado (6) OU domingo (7).
if (dia == 6 || dia == 7) {
printf("Fim de semana!\n");
}
// Nega uma condição:
if (!chovendo) {
printf("Bom dia para um passeio.\n");
}
Como escrever 'x entre a e b' — NÃO copie da matemática
Na matemática você escreve 0 <= x <= 100. Em C isso não faz o que você quer (é
interpretado de forma estranha e quase sempre dá "sempre verdadeiro"). O correto é
quebrar em duas comparações ligadas por &&:
Curiosidade 💡 — avaliação em curto-circuito (e por que é útil)
O C avalia && e || da esquerda para a direita e para assim que já sabe o
resultado:
- Em
A && B, seAfor falso,Bnem é avaliado (o resultado já é falso). - Em
A || B, seAfor verdadeiro,Bnem é avaliado.
Isso não é só uma otimização: permite proteger um teste com o anterior. Por exemplo, evitar dividir por zero — só testamos a divisão se o divisor não for zero:
Sedivisor for 0, o primeiro teste falha e o segundo (a divisão) nunca acontece.
Curiosidade 💡 — as Leis de De Morgan
Negar uma combinação de condições tem uma regra elegante:
!(A && B) equivale a (!A || !B), e !(A || B) equivale a (!A && !B). Ou seja,
ao "distribuir" o !, o && vira || e vice-versa. Útil para simplificar condições
complicadas e deixá-las mais legíveis.
8. Condicionais aninhadas¶
Um if pode conter outro if no seu corpo. Isso é o aninhamento, útil quando uma
decisão só faz sentido depois de outra já ter sido tomada:
int numero;
scanf("%d", &numero);
if (numero >= 0) {
if (numero == 0) {
printf("Zero\n");
} else {
printf("Positivo\n");
}
} else {
printf("Negativo\n");
}
Leia assim: primeiro decidimos se é não-negativo; só então, dentro desse caso, distinguimos zero de positivo.
Aninhar demais é sinal de alerta
Muitos níveis de if dentro de if deixam o código difícil de acompanhar (o chamado
"código em escada"). Frequentemente dá para achatar a estrutura usando else if
ou combinando condições com &&/||. Compare:
Curiosidade 💡 — o dangling else (o 'else solto')
Quando há ifs aninhados sem chaves, a qual if um else pertence? A regra do C é:
o else sempre casa com o if mais próximo ainda "em aberto". Essa ambiguidade,
conhecida como dangling else, é justamente mais um motivo para sempre usar
chaves — com elas, não há dúvida possível.
9. switch: múltipla escolha por valor exato¶
Quando você compara uma mesma variável contra vários valores fixos, uma cadeia de
else if fica repetitiva. O switch expressa isso de forma mais limpa:
int opcao;
printf("1-Iniciar 2-Configurar 3-Sair\nEscolha: ");
scanf("%d", &opcao);
switch (opcao) {
case 1:
printf("Iniciando...\n");
break;
case 2:
printf("Abrindo configuracoes...\n");
break;
case 3:
printf("Saindo. Ate logo!\n");
break;
default:
printf("Opcao invalida.\n");
}
Como funciona: o switch avalia a expressão e salta para o case cujo valor bate. O
break encerra o switch. O default (opcional) trata qualquer valor não
previsto.
O break esquecido e o fall-through
Sem break, a execução "escorrega" para o próximo case — e continua até achar um
break ou o fim. Isso se chama fall-through:
switch (opcao) {
case 1:
printf("Um\n"); // se opcao == 1 e faltar o break...
case 2:
printf("Dois\n"); // ...esta linha TAMBÉM executa!
break;
}
break em
todo case.
Limitações do switch
O switch só compara igualdade com valores inteiros constantes (inclui char,
pois é inteiro). Ele não funciona com intervalos (case > 10: é inválido) nem
com double ou strings. Para intervalos e testes mais ricos, use if/else if.
Curiosidade 💡 — fall-through usado de propósito
Há um caso legítimo: agrupar vários valores que compartilham a mesma ação, deixando
cases "vazios" caírem no seguinte:
10. Bônus: o operador ternário ?:¶
Para decisões simples que apenas escolhem um valor, existe uma forma compacta, o operador condicional ternário:
// condição ? valor_se_verdadeiro : valor_se_falso
int maior = (a > b) ? a : b; // maior recebe a ou b
printf("%s\n", (nota >= 6) ? "Aprovado" : "Reprovado");
Ele equivale a um if/else que decide um valor. Use com moderação: para lógica mais
elaborada, o if/else tradicional é mais legível.
11. Erros comuns desta semana (resumão)¶
Checklist de armadilhas
-
=(atribui) no lugar de==(compara) dentro doif. -
;logo apósif (...)— cria corpo vazio. - Esquecer as chaves e achar que várias linhas estão no
if. - Escrever intervalo como
0 <= x <= 100(usex >= 0 && x <= 100). - Ordem errada em cadeias
else if(condição genérica antes da específica). -
breakesquecido noswitch(fall-through acidental). - Usar
switchcom intervalos,doubleou strings (não funciona).
👥 Quarta — Encontro¶
Chegue tendo estudado e executado os exemplos. No encontro vamos:
- Transformar enunciados em árvores de decisão (fluxogramas) e daí em código.
- Discutir quando usar
else if×switch×&&/||× aninhamento. - Caçar, ao vivo, os erros da seção 11 — especialmente
=/==ebreakesquecido.
Problema-guia — classificador de IMC: ler peso e altura, calcular o Índice de Massa
Corporal (IMC = peso / (altura * altura)) e classificar em faixas.
#include <stdio.h>
int main(void) {
double peso, altura;
printf("Peso (kg): ");
scanf("%lf", &peso);
printf("Altura (m): ");
scanf("%lf", &altura);
double imc = peso / (altura * altura);
printf("IMC = %.1f -> ", imc);
if (imc < 18.5) {
printf("Abaixo do peso\n");
} else if (imc < 25.0) {
printf("Peso normal\n");
} else if (imc < 30.0) {
printf("Sobrepeso\n");
} else {
printf("Obesidade\n");
}
return 0;
}
Para pensar antes: por que a cadeia usa só imc < X em cada faixa, sem &&? (Dica:
reveja a seção 6.)
✍️ Sexta — Estudo dirigido¶
Exercícios guiados (Beecrowd)¶
Resolva, em C, na ordem sugerida:
| Nº | Problema | O que exercita |
|---|---|---|
| 1035 | Teste de Seleção 1 | if/else com condições combinadas |
| 1038 | Lanche | switch como tabela de preços |
| 1037 | Intervalo | cadeia else if com faixas |
| 1041 | Coordenadas de um Ponto | aninhamento (quadrantes, eixos, origem) |
| 1042 | Ordena os 3 Valores | condições cuidadosas |
| 1043 | Triângulo | validação + classificação |
| 1044 | Múltiplos | uso de % numa condição |
| 1046 | Intervalo de Tempo | lógica com decisão |
| 1052 | Mês | switch com default |
Desafios para escrever do zero¶
- Sinal do número: ler um inteiro e dizer se é positivo, negativo ou zero.
- Par ou ímpar: ler um inteiro e classificar (use
% 2). - Maior de três: ler três números e imprimir o maior — faça uma versão com
if/elseaninhado e outra com o operador ternário. - Classificador de triângulo: ler três lados; primeiro decidir se formam um triângulo (a soma de dois quaisquer > o terceiro); se sim, classificar em equilátero, isósceles ou escaleno.
- Calculadora com menu: ler dois números e uma operação (
+,-,*,/) comochar; usarswitchpara calcular. Trate a divisão por zero com uma mensagem. - Ano bissexto: ler um ano e dizer se é bissexto (divisível por 4, exceto os
divisíveis por 100 que não sejam por 400). Ótimo exercício de
&&/||.
Para investigar (curiosidade prática)¶
- O que imprime
if (5) printf("A\n");? Eif (0) printf("B\n");? Relacione com a seção 2 (verdadeiro/falso em C). - Reescreva a condição
!(idade >= 18 && tem_documento)usando as Leis de De Morgan (seção 7) e confira que o comportamento é o mesmo.
✅ Checklist de autoavaliação¶
- Explico o que é controle de fluxo e desenho a decisão como fluxograma.
- Escrevo
if,if/elsee cadeiaselse ifcorretas, sempre com chaves. - Combino condições com
&&,||,!e sei escrever "x entre a e b". - Entendo a avaliação em curto-circuito e sei usá-la para proteger testes.
- Sei quando aninhar e quando achatar condições.
- Uso
switchcombreak, conheço o fall-through e as limitações da estrutura. - Não caio nas armadilhas
=/==,;após oife intervalo0 <= x <= 100.
🔗 Referências e para se aprofundar¶
- Material 2026.1 — Aula 02: Estruturas Condicionais.
- BACKES, André. Linguagem C: completa e descomplicada (estruturas de decisão).
- KERNIGHAN, B.; RITCHIE, D. The C Programming Language, cap. 3 (controle de fluxo).
- MIZRAHI, Victorine V. Treinamento em Linguagem C (comandos de decisão).
- Referência: cppreference — if · switch.
- Prática: Beecrowd.
Antes de seguir para a Semana 03
Decisões são metade do controle de fluxo; a outra metade é a repetição, que vem na
próxima semana. Garanta que você consegue, sozinho(a), escrever um if/else if
correto e um switch com break — vamos combiná-los com laços muito em breve.