📚 Capítulo do curso: 05 — Estruturas Condicionais, Decisão e Operador Ternário da Especialização em Sistemas com C. Leia o capítulo antes de começar.
Um simulador de sensor de temperatura que classifica uma leitura fixa em FRIO/NORMAL/QUENTE/CRÍTICO — primeiro com if/else if/else, depois com um switch-case equivalente, e por fim com um operador ternário.
🔒 Regra de Ouro: o Capítulo 05 libera
if/else if/else,switch-casee o operador ternário?:— o primeiro miniprojeto da especialização com desvio de fluxo real. Ainda sem laços (while/for) nem funções auxiliares: cada leitura do sensor precisa de um bloco de decisão escrito manualmente. Essa repetição de blocos de decisão idênticos, para leituras diferentes, é o problema que os laços resolvem a partir do Miniprojeto 06 (while) e do Miniprojeto 07 (for).
| ⏱️ Tempo estimado | 📦 Você vai entregar | ✅ Pronto quando |
|---|---|---|
| 40 min | main.c |
compila sem avisos e if/else e switch concordam no estado |
if / else if / else, cobrindo múltiplos ramos mutuamente exclusivos.switch-case sobre um valor discretizado, incluindo a cláusula default.?: para escolher, numa única expressão, entre duas mensagens curtas.if/else e switch-case são equivalentes e onde cada um se encaixa melhor.Você está prototipando o firmware de um sensor de temperatura industrial (main.c). Para uma leitura fixa int leitura = 38; (graus Celsius), o programa deve:
if / else if / else, com pelo menos 4 ramos.switch-case sobre uma faixa discretizada (leitura / 10), com uma cláusula default cobrindo os casos não mapeados explicitamente.?: para decidir uma mensagem curta de alerta ("ALERTA" se a leitura for muito alta, "OK" caso contrário).| ID | Requisito |
|---|---|
| RF01 | O programa deve compilar sem nenhum aviso com gcc -Wall -Wextra -Wpedantic -std=c17. |
| RF02 | Deve conter #include <stdio.h> e #include <stdlib.h>, usar int main(void) e terminar com return EXIT_SUCCESS;. |
| RF03 | Não pode usar while, for ou funções além de main (laços e funções ainda não foram liberados). |
| RF04 | Deve classificar leitura = 38 em FRIO/NORMAL/QUENTE/CRÍTICO usando if / else if / else, com pelo menos 4 ramos. |
| RF05 | Deve repetir a classificação usando switch-case sobre leitura / 10, incluindo uma cláusula default. |
| RF06 | Deve usar o operador ternário ?: pelo menos uma vez para decidir uma mensagem curta. |
| RF07 | Para leitura = 38, o if/else e o switch-case devem produzir o mesmo estado (QUENTE). |
graph TD
A["main() inicia\nleitura = 38, faixa = leitura / 10"] --> C{"if / else if / else"}
C -->|"leitura < 20"| D["FRIO"]
C -->|"leitura < 30"| E["NORMAL"]
C -->|"leitura < 50"| F["QUENTE"]
C -->|"else"| G["CRITICO"]
A --> H{"switch(faixa)"}
H -->|"0, 1"| D
H -->|"2"| E
H -->|"3, 4"| F
H -->|"default"| G
A --> I["ternario:\nleitura >= 45 ? ALERTA : OK"]
D --> J["return EXIT_SUCCESS"]
E --> J
F --> J
G --> J
I --> J
style C fill:#0284c7,stroke:#38bdf8,color:#ffffff
style H fill:#0d9488,stroke:#2dd4bf,color:#ffffff
style I fill:#7c3aed,stroke:#a78bfa,color:#ffffff
style J fill:#059669,stroke:#34d399,color:#ffffff
O mesmo do Miniprojeto 01: gcc 8 ou mais novo. No Windows, rode chcp 65001 se os emojis aparecerem quebrados.
🎯 Objetivo: partir de um código que compila e roda, antes de escrever qualquer linha.
⌨️ Faça: crie a pasta c_mini_05, salve o código abaixo como main.c e rode:
gcc -Wall -Wextra -Wpedantic -std=c17 main.c -o app
./app # Linux/macOS
.\app.exe # Windows (PowerShell)
📄 src/esqueleto.c
/*
* Miniprojeto 05: Motor de Decisao e Maquina de Estados Finitos
* Regra: if/else if/else, switch-case, operador ternario.
* Ainda SEM lacos (while/for) nem funcoes auxiliares.
*/
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int leitura = 38; // leitura fixa do sensor de temperatura (graus Celsius)
int faixa = leitura / 10; // discretiza a leitura em faixas de 10 em 10
printf("====================================================\n");
printf(" MOTOR DE DECISAO - SENSOR DE TEMPERATURA\n");
printf("====================================================\n");
printf("Leitura bruta do sensor: %d C (faixa = %d)\n\n", leitura, faixa);
// TODO 1: classifique "leitura" em FRIO/NORMAL/QUENTE/CRITICO usando
// if / else if / else, com pelo menos 4 ramos. Imprima o resultado
// prefixado com "[if/else] Estado: ".
// Sugestao de limites: < 20 FRIO | < 30 NORMAL | < 50 QUENTE | senao CRITICO
// TODO 2: repita a classificacao usando switch(faixa), com um case para
// cada faixa e uma clausula default. Imprima prefixado com
// "[switch] Estado: ". Nao esqueca do break em cada case!
// TODO 3: use o operador ternario para decidir entre "ALERTA" e "OK"
// com base em (leitura >= 45). Imprima prefixado com "[ternario] Alerta: "
printf("====================================================\n");
return EXIT_SUCCESS;
}
✅ Checkpoint: zero avisos do gcc, e a saída é:
🖥️ Saída esperada:
====================================================
MOTOR DE DECISAO - SENSOR DE TEMPERATURA
====================================================
Leitura bruta do sensor: 38 C (faixa = 3)
====================================================
if / else if / else (TODO 1)🎯 Objetivo: escrever a primeira cadeia de decisão com ramos mutuamente exclusivos.
⌨️ Faça: imprima [if/else] Estado: e, numa cadeia de 4 ramos, complete com FRIO (< 20), NORMAL (< 30), QUENTE (< 50) ou CRITICO (o resto).
💡 A ordem importa: cada
else ifsó é avaliado se todos os anteriores deram falso. Por issoleitura < 50já significa “entre 30 e 49”.
✅ Checkpoint: aparece a linha [if/else] Estado: QUENTE.
🧯 Se der errado: se sai NORMAL ou FRIO para 38, a comparação está invertida (> no lugar de <) ou os ramos estão fora de ordem.
switch (TODO 2)🎯 Objetivo: ver que switch só compara igualdade com constantes, e por isso precisa da faixa discretizada.
⌨️ Faça: imprima [switch] Estado: e escreva switch (faixa) com case 0: case 1: → FRIO, case 2: → NORMAL, case 3: case 4: → QUENTE e default: → CRITICO, cada bloco terminando em break;.
✅ Checkpoint: aparece [switch] Estado: QUENTE, igual ao if/else.
🧯 Se der errado:
QUENTE e logo depois CRITICO: faltou o break no case 4, e a execução “caiu” para o default. O gcc avisa com this statement may fall through (-Wimplicit-fallthrough, ligado pelo -Wextra).case label does not reduce to an integer constant: você tentou case leitura < 30:. O case só aceita constantes.🎯 Objetivo: escolher entre dois valores numa única expressão.
⌨️ Faça: printf("[ternario] Alerta: %s\n", (leitura >= 45) ? "ALERTA" : "OK");
✅ Checkpoint: [ternario] Alerta: OK, porque 38 < 45.
🎯 Objetivo: validar a saída completa e o código de retorno.
✅ Checkpoint: a saída é esta, e o código de retorno é 0 (echo $? no Linux/macOS ou echo $LASTEXITCODE no PowerShell):
🖥️ Saída esperada:
====================================================
⚡ MOTOR DE DECISAO - SENSOR DE TEMPERATURA
====================================================
Leitura bruta do sensor: 38 C (faixa = 3)
[if/else] Estado: QUENTE
[switch] Estado: QUENTE
[ternario] Alerta: OK
====================================================
Só abra o gabarito depois de chegar até aqui:
src/main.c📄 src/main.c
/*
* Miniprojeto 05: Motor de Decisao e Maquina de Estados Finitos
* Especializacao em Engenharia de Sistemas em C
* Regra: if/else if/else, switch-case, operador ternario.
*/
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int leitura = 38; // leitura fixa do sensor de temperatura (graus Celsius)
int faixa = leitura / 10; // discretiza a leitura em faixas de 10 em 10
printf("====================================================\n");
printf(" ⚡ MOTOR DE DECISAO - SENSOR DE TEMPERATURA\n");
printf("====================================================\n");
printf("Leitura bruta do sensor: %d C (faixa = %d)\n\n", leitura, faixa);
// ---- Classificacao via if / else if / else (4 ramos) ----
printf("[if/else] Estado: ");
if (leitura < 20) {
printf("FRIO\n");
} else if (leitura < 30) {
printf("NORMAL\n");
} else if (leitura < 50) {
printf("QUENTE\n");
} else {
printf("CRITICO\n");
}
// ---- Classificacao equivalente via switch-case sobre a faixa ----
printf("[switch] Estado: ");
switch (faixa) {
case 0:
case 1:
printf("FRIO\n");
break;
case 2:
printf("NORMAL\n");
break;
case 3:
case 4:
printf("QUENTE\n");
break;
default:
printf("CRITICO\n");
break;
}
// ---- Operador ternario: mensagem curta de alerta ----
printf("[ternario] Alerta: %s\n", (leitura >= 45) ? "ALERTA" : "OK");
printf("====================================================\n");
return EXIT_SUCCESS;
}
Por que isso importa: repare que o switch não compara leitura diretamente — ele compara a faixa discretizada (leitura / 10), porque switch em C só aceita comparação de igualdade exata contra constantes inteiras, nunca uma faixa como < 30. É por isso que case 0: “cai” (fall-through, propositalmente sem break) para dentro de case 1:, e case 3: cai para dentro de case 4:: assim um único bloco de código atende a duas faixas numéricas consecutivas.
Altere manualmente o valor de leitura para testar os 4 estados (ex: 5, 22, 38, 60), recompilando o programa a cada mudança. Perceba que testar vários valores exige editar o código-fonte e recompilar toda vez — essa limitação será resolvida assim que você combinar scanf com laços no Miniprojeto 06 (Capítulo 06 — laços while), quando o programa poderá ler leituras do sensor continuamente, sem recompilar, até o usuário decidir parar.
✅ Checkpoint: os dois métodos concordam em 5 → FRIO, 22 → NORMAL, 38 → QUENTE e 60 → CRITICO. O ternário só dá ALERTA a partir de 45.
🔎 Pegadinha: teste leitura = -15. O if/else diz FRIO, mas o switch diz CRITICO. Isso acontece porque a divisão inteira em C trunca em direção a zero: -15 / 10 dá -1, que não tem case e cai no default. Como você corrigiria o switch sem mexer no if?
📋 Projetos do curso de C | 📚 Teoria do Capítulo 05 | 🗂️ Hub de projetos