📚 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.

🚦 Miniprojeto C 05 — Motor de Decisão e Máquina de Estados

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-case e 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

Diagrama do 🚦 Miniprojeto C 05 — Motor de Decisão e Máquina de Estados

🎯 Objetivos

📋 O problema

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:

  1. Classificar o estado do sensor em FRIO, NORMAL, QUENTE ou CRÍTICO usando if / else if / else, com pelo menos 4 ramos.
  2. Repetir uma classificação equivalente usando switch-case sobre uma faixa discretizada (leitura / 10), com uma cláusula default cobrindo os casos não mapeados explicitamente.
  3. Usar o operador ternário ?: 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

🧰 Ambiente

O mesmo do Miniprojeto 01: gcc 8 ou mais novo. No Windows, rode chcp 65001 se os emojis aparecerem quebrados.


Passo 1 — Compilar o esqueleto

🎯 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)

====================================================

Passo 2 — Classificar com 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 if só é avaliado se todos os anteriores deram falso. Por isso leitura < 50 já 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.


Passo 3 — A mesma decisão com 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:


Passo 4 — Ternário (TODO 3)

🎯 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.


Passo final — Conferir com o gabarito

🎯 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:

🔑 Ver gabarito: 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.


🏆 Desafio

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?


🧭 Navegação

📋 Projetos do curso de C | 📚 Teoria do Capítulo 05 | 🗂️ Hub de projetos