Tomando decisões em C — condições simples, duplas e fluxo de controle
Programas raramente executam sempre o mesmo caminho. A maioria das situações reais exige que o código tome decisões: verificar se uma senha está correta, determinar se um número é positivo ou negativo, ou escolher qual mensagem exibir ao usuário. Para isso existem as estruturas de decisão.
0 é falso e qualquer valor diferente de zero é verdadeiro.
if — executa um bloco se a condição for verdadeiraif-else — escolhe entre dois blocos (verdadeiro ou falso)if-else if-else — cadeia de condições múltiplas (Aula 09)switch-case — seleção por valor discreto (Aula 09)?: — decisão compacta em uma linha (Aula 09)if e if-else.
A estrutura if executa um bloco de código somente se a condição for verdadeira. Se a condição for falsa, o bloco é simplesmente pulado.
if (condição) {
// bloco executado apenas se condição for verdadeira
}
#include <stdio.h>
int main() {
int isStudent = 1; // 1 = verdadeiro
int temperatura = 38;
// if simples: só executa se isStudent for não-zero
if (isStudent) {
printf("Você é estudante.\n");
}
// if com operador relacional
if (temperatura > 37.5) {
printf("Atenção: temperatura elevada (%.1f°C).\n", (float)temperatura);
}
printf("Fim do programa.\n"); // sempre executado
return 0;
}
Você é estudante.
Atenção: temperatura elevada (38.0°C).
Fim do programa.
Quando o bloco do if tem apenas uma instrução, as chaves são opcionais em C. Porém, omiti-las é uma fonte frequente de bugs:
// Válido — mas arriscado if (temperatura > 37.5) printf("Febre!\n"); // única instrução: pertence ao if printf("Consulte um médico.\n"); // SEMPRE executa — fora do if! // Seguro — sempre use chaves if (temperatura > 37.5) { printf("Febre!\n"); printf("Consulte um médico.\n"); // agora pertence ao bloco do if }
{ } em blocos if, mesmo quando há apenas uma instrução. Isso evita o bug clássico de adicionar uma segunda linha acreditando que ela também faz parte do if — quando na realidade está fora dele.
A estrutura if-else permite escolher entre dois caminhos: um executado quando a condição é verdadeira e outro quando é falsa. Exatamente um dos dois blocos sempre será executado.
if (condição) {
// bloco executado se condição for VERDADEIRA
} else {
// bloco executado se condição for FALSA
}
#include <stdio.h>
int main() {
int age = 20;
// if-else: exatamente um dos blocos será executado
if (age < 18) {
printf("Menor de idade.\n");
} else {
printf("Maior de idade.\n"); // este executa (20 >= 18)
}
// Verificando par ou ímpar
int numero = 7;
if (numero % 2 == 0) {
printf("%d é par.\n", numero);
} else {
printf("%d é ímpar.\n", numero); // este executa
}
return 0;
}
Maior de idade.
7 é ímpar.
Estruturas if-else podem ser colocadas dentro de outras — chamamos isso de aninhamento. Isso permite verificar condições progressivamente mais específicas.
#include <stdio.h>
int main() {
int nota = 75;
int faltas = 5;
if (nota >= 60) {
// nota suficiente — mas e as faltas?
if (faltas <= 25) {
printf("Aprovado: nota %.0d e frequência suficiente.\n", nota);
} else {
printf("Reprovado por falta, apesar da nota %d.\n", nota);
}
} else {
printf("Reprovado por nota insuficiente: %d.\n", nota);
}
return 0;
}
Aprovado: nota 75 e frequência suficiente.
else sempre se associa ao if mais próximo acima dele. Se as chaves forem omitidas em aninhamentos, o compilador pode interpretar o código de forma diferente da intenção do programador. Use sempre chaves para deixar o agrupamento explícito.
// Ambíguo sem chaves — a qual if pertence o else? if (a > 0) if (b > 0) printf("ambos positivos\n"); else // associa ao "if (b > 0)", não ao "if (a > 0)"! printf("b não é positivo\n"); // Claro com chaves if (a > 0) { if (b > 0) { printf("ambos positivos\n"); } } else { // agora claramente pertence ao "if (a > 0)" printf("a não é positivo\n"); }
A condição de um if pode combinar múltiplos operadores relacionais e lógicos para expressar critérios mais complexos:
#include <stdio.h>
int main() {
int idade = 22;
float salario = 3500.0;
int temCPF = 1;
// Aprovação de crédito: múltiplas condições com && e ||
if (idade >= 18 && salario >= 2000.0 && temCPF) {
printf("Crédito aprovado.\n");
} else {
printf("Crédito negado.\n");
}
// Verificação de faixa de temperatura
float temp = 36.8;
if (temp >= 36.0 && temp <= 37.5) {
printf("Temperatura normal: %.1f°C\n", temp);
} else {
printf("Temperatura fora do normal: %.1f°C\n", temp);
}
// Acesso por categoria
int vip = 0, convidado = 1;
if (vip || convidado) {
printf("Acesso liberado ao evento.\n");
}
return 0;
}
Crédito aprovado.
Temperatura normal: 36.8°C
Acesso liberado ao evento.
O trecho abaixo, extraído diretamente da seção 5 do livro de referência do curso, demonstra o if simples e o if-else aplicados a um cenário de controle de acesso:
#include <stdio.h>
int main() {
int age = 25;
int isStudent = 1;
// if simples: executa apenas se isStudent for verdadeiro
if (isStudent) {
printf("You are a student.\n");
}
// if-else: escolhe entre dois caminhos
if (age < 18) {
printf("Underage.\n");
} else {
printf("Of legal age.\n");
}
return 0;
}
You are a student.
Of legal age.
if (isStudent) é equivalente a if (isStudent != 0). Como isStudent = 1 (não-zero), a condição é verdadeira. Essa forma concisa é idiomática em C e amplamente usada com variáveis que funcionam como flags (ligado/desligado).
Aplicando if-else a um contexto do curso — análise do sinal de energia calculada:
#include <stdio.h>
int main() {
double energia = -74.96; // energia em Hartree (valor típico do H₂O)
printf("Energia calculada: %.4f Hartree\n", energia);
if (energia < 0) {
printf("Sistema estável: energia negativa indica estado ligado.\n");
} else {
printf("Sistema instável: energia positiva indica estado não ligado.\n");
}
// Verificando convergência do cálculo
double delta = 0.000003; // diferença entre iterações
double tolerancia = 1e-5; // critério de convergência
if (delta <= tolerancia) {
printf("Cálculo convergido (delta = %.2e).\n", delta);
} else {
printf("Cálculo ainda não convergiu (delta = %.2e).\n", delta);
}
return 0;
}
Energia calculada: -74.9600 Hartree
Sistema estável: energia negativa indica estado ligado.
Cálculo convergido (delta = 3.00e-06).
A sintaxe de if e if-else é praticamente idêntica nas duas linguagens. As diferenças estão no sistema de tipos e no que é aceito como condição:
| Aspecto | C | Java |
|---|---|---|
Sintaxe do if |
if (condição) { } |
if (condição) { } (idêntica) |
Sintaxe do if-else |
if (...) { } else { } |
if (...) { } else { } (idêntica) |
| Tipo da condição | Qualquer inteiro — 0 é falso, não-zero é verdadeiro | Deve ser boolean — true ou false |
if (x) com inteiro |
Válido — compila sem erro | Inválido — erro de compilação |
if (x = 5) (atribuição) |
Compila sem erro — bug silencioso | Erro de compilação (tipo incompatível) |
| Chaves opcionais (bloco único) | Sim — mas não recomendado | Sim — mas não recomendado |
| Dangling else | Ocorre sem chaves — else ao if mais próximo | Mesma regra — idêntico ao C |
| C | Java |
|---|---|
int age = 20;
int isStudent = 1;
if (isStudent) {
printf("Estudante.\n");
}
if (age < 18) {
printf("Menor.\n");
} else {
printf("Maior.\n");
}
|
int age = 20;
boolean isStudent = true;
if (isStudent) {
System.out.println("Estudante.");
}
if (age < 18) {
System.out.println("Menor.");
} else {
System.out.println("Maior.");
}
|
Teste seus conhecimentos sobre estruturas if e if-else em C: