⚡ Cap 05: Estruturas Condicionais, Decisão e Operador Ternário
Bem-vindo ao quinto capítulo da Especialização em Engenharia de Sistemas com Linguagem C (C17/C23)! ⚡
Até este momento, nossos programas executavam comandos de forma estritamente sequencial (uma linha após a outra). Neste capítulo, você aprenderá como alterar o fluxo de execução através da tomada de decisões lógicas, utilizando if, if...else, if...else if...else, seleção múltipla com switch-case e expressões compactas com o Operador Condicional Ternário (?:).
🗺️ Mapa Conceitual do Capítulo
graph TD
A["Controle de Fluxo Condicional em C"] --> B["1. Estruturas if / else"]
A --> C["2. Seleção switch-case"]
A --> D["3. Operador Ternário (?:)"]
A --> E["4. Boas Práticas & Segurança"]
B --> B1["if simples, if-else binário, if-else if múltiplos caminhos"]
C --> C1["Chaveamento de inteiros/char, papel do break, default"]
D --> D1["Atribuição inline, uso em printf, ternários aninhados"]
E --> E1["Chaves obrigatórias {}, prevenção de Dangling Else, CERT C"]
🔀 1. A Família if, if...else e if...else if...else
Em C, uma condição é uma expressão avaliada como verdadeira (qualquer valor numérico diferente de 0) ou falsa (exatamente igual a 0).
1. if Simples (Decisão Unilateral)
Executa um bloco de instruções apenas se a condição for verdadeira:
if (temperatura > 100.0) {
printf("Alerta: Temperatura critica atingida!\n");
}
2. if...else (Decisão Binária)
Garante a execução de exatamente um dos dois caminhos mutuamente exclusivos:
if (saldo >= valorSaque) {
saldo -= valorSaque;
printf("Saque realizado com sucesso.\n");
} else {
printf("Saldo insuficiente para a operacao.\n");
}
3. if...else if...else (Múltiplas Faixas de Decisão)
Avalia condições sequencialmente até encontrar a primeira verdadeira. A ordem das condições é crucial:
// ✅ ORDEM CORRETA (Do mais restritivo para o mais amplo)
if (pontuacao >= 90) {
printf("Classificacao: Ouro 🥇\n");
} else if (pontuacao >= 70) {
printf("Classificacao: Prata 🥈\n");
} else if (pontuacao >= 50) {
printf("Classificacao: Bronze 🥉\n");
} else {
printf("Nao classificado ❌\n");
}
⚠️ 2. Aninhamento de Condicionais & O Problema do Dangling Else
Quando múltiplos if e else são aninhados sem chaves, a linguagem C vincula o else ao if imediatamente anterior, o que pode gerar comportamentos inesperados:
// ❌ CÓDIGO AMBÍGUO (Dangling Else):
if (usuarioAutenticado)
if (eAdministrador)
printf("Acesso total concedido.\n");
else
printf("Acesso negado.\n"); // Esse else pertence ao 'eAdministrador'!
// ✅ CÓDIGO SEGURO E EXPLÍCITO (Com Chaves):
if (usuarioAutenticado) {
if (eAdministrador) {
printf("Acesso total concedido.\n");
}
} else {
printf("Acesso negado.\n"); // Agora pertence ao 'usuarioAutenticado'!
}
🎯 3. Seleção Múltipla com switch-case
A estrutura switch-case realiza desvios condicionais baseados no valor exato de uma expressão inteira ou caractere (char). Internamente, compiladores modernos geram uma tabela de saltos (Jump Table) em tempo constante $O(1)$:
switch (codigoComando) {
case 1:
iniciarProcesso();
break; // Impede a execução dos casos seguintes (Fall-through)
case 2:
pausarProcesso();
break;
case 3:
reiniciarProcesso();
break;
default:
fprintf(stderr, "Comando desconhecido: %d\n", codigoComando);
break;
}
[!WARNING] O Perigo do Fall-Through: Se você esquecer a instrução
break;no final de umcase, o programa continuará executando as instruções do próximocaseabaixo dele, mesmo que a condição dele não seja correspondente!
⚡ 4. O Operador Condicional Ternário (?:)
O operador ternário é a única operação da Linguagem C que aceita três operandos:
\[\text{Condicao} \quad \mathbf{?} \quad \text{Expressao se Verdadeiro} \quad \mathbf{:} \quad \text{Expressao se Falso}\]Casos de Uso Mais Frequentes:
- Atribuição Direta de Variáveis:
int maior = (a > b) ? a : b; - Uso Inline no
printf():printf("O sensor esta %s.\n", (sensorAtivo) ? "LIGADO" : "DESLIGADO"); - Classificação com Ternários Aninhados:
const char *conceito = (media >= 9.0) ? "Excelente" : (media >= 7.0) ? "Aprovado" : (media >= 5.0) ? "Recuperacao" : "Reprovado";
🛡️ 5. Boas Práticas e Segurança de Código (CERT C)
- Chaves Obrigatórias em Todos os Blocos: Nunca omita as chaves
{ ... }, mesmo em comandos de uma única linha. A falha de segurança histórica da Apple (goto fail bug em SSL) ocorreu por falta de chaves em um blocoif. - Nunca use
=dentro doif:- ❌
if (nivelAcesso = 1)atribui 1 e sempre avalia como verdadeiro! - ✅
if (nivelAcesso == 1)compara o valor corretamente.
- ❌
- Coloque Constantes à Esquerda (Yoda Conditions):
- Escrever
if (1 == nivelAcesso)gera erro de compilação imediato caso você digite acidentalmente um único=, prevenindo bugs silenciosos.
- Escrever
🔍 6. Diagnóstico & Resolução de Problemas (Troubleshooting)
| Sintoma Observado | Causa Provável | Como Resolver |
|---|---|---|
O switch executa todos os blocos de uma vez |
Esquecimento do comando break; no final dos blocos case. |
Adicione break; ao término de cada case. |
Erro de compilação: switch quantity not an integer |
Tentativa de usar switch com tipos de ponto flutuante (float, double) ou strings. |
O switch suporta apenas tipos inteiros e char. Para double ou strings, use if-else if. |
O bloco else executa mesmo quando a condição deveria ser verdadeira |
Ponto e vírgula indevido após o if (ex: if (x > 0); { ... }). |
Remova o ponto e vírgula ; após o parêntese do if. |
🏆 7. Desafio Prático de Consolidação
Enunciado do Desafio:
Desenvolva um programa em C chamado classificador_voo.c que simule o sistema de despacho de uma torre de controle:
- Solicite ao operador a velocidade atual do vento em km/h (
double) e a visibilidade em metros (int). - Utilize
if...else if...elsecom condições compostas (&&,||) para classificar a pista:- Voo Livre (Verde): Vento $< 30$ km/h E Visibilidade $\ge 5000$ m.
- Voo por Instrumentos (Amarelo): Vento entre $30$ e $60$ km/h OU Visibilidade entre $1500$ e $4999$ m.
- Pista Fechada (Vermelho): Vento $\ge 60$ km/h OU Visibilidade $< 1500$ m.
- Exiba a situação final utilizando um operador ternário formatado no
printf.
🔍 Ver Solução Comentada do Desafio
#include <stdio.h>
#include <stdbool.h>
typedef enum {
MODO_DESLIGADO = 0,
MODO_RESFRIAMENTO = 1,
MODO_AQUECIMENTO = 2,
MODO_EMERGENCIA = 99
} ModoOperacao;
int main(void) {
double temp = 38.5;
ModoOperacao modo;
// Decisao por faixas com if-else e operador ternario
if (temp > 50.0) {
modo = MODO_EMERGENCIA;
} else if (temp > 30.0) {
modo = MODO_RESFRIAMENTO;
} else if (temp < 15.0) {
modo = MODO_AQUECIMENTO;
} else {
modo = MODO_DESLIGADO;
}
// Processamento com switch-case
printf("Temperatura Medida: %.1lf C -> ", temp);
switch (modo) {
case MODO_RESFRIAMENTO:
printf("Ativando Refrigeracao Industrial! ❄️\n");
break;
case MODO_AQUECIMENTO:
printf("Ativando Aquecedores de Seguranca! 🔥\n");
break;
case MODO_EMERGENCIA:
printf("ALERTA CRITICO: Desligamento Emergencial! 🚨\n");
break;
case MODO_DESLIGADO:
default:
printf("Temperatura Estavel. Sistema em Standby. 💤\n");
break;
}
return 0;
}
🧭 Navegação Rápida
| 📖 Teoria | 📊 Slides | 🧠 Quiz | 💻 Exemplos | 🧩 Exercícios | | :— | :— | :— | :— | :— | | Ler Teoria | Ver Slides | Fazer Quiz | Ver Exemplos | Praticar Exercícios |
🧭 Navegação do Capítulo: ⬅️ Capítulo Anterior · 📚 Sumário do Módulo · ➡️ Próximo Capítulo