Condicionais: if, else e switch
1. Introdução às Estruturas Condicionais
As estruturas condicionais são o coração da tomada de decisão em qualquer programa. Em Linguagem C, elas permitem que o fluxo de execução do código seja desviado com base em condições avaliadas em tempo de execução. Sem condicionais, todo programa seria uma sequência linear de instruções, incapaz de reagir a diferentes entradas ou estados.
O mecanismo fundamental por trás das condicionais em C é a avaliação de expressões como verdadeiras ou falsas. Diferente de outras linguagens, C não possui um tipo booleano nativo (até C99, com _Bool). Em C, qualquer valor diferente de zero é considerado verdadeiro, e o valor zero é considerado falso. Essa característica é essencial para entender o comportamento de if, else e switch.
2. O Comando if
A sintaxe básica do comando if é:
if (expressão) {
// bloco de código executado se expressão for verdadeira
}
A expressão entre parênteses é avaliada. Se o resultado for diferente de zero, o bloco de código é executado. Caso contrário, o fluxo segue para a próxima instrução após o if.
Exemplo prático: verificar se um número é positivo.
#include <stdio.h>
int main() {
int numero = 10;
if (numero > 0) {
printf("O número %d é positivo.\n", numero);
}
return 0;
}
O uso de chaves {} é obrigatório quando o bloco contém mais de uma instrução. Para uma única instrução, as chaves são opcionais, mas é uma boa prática sempre utilizá-las para evitar erros de interpretação e melhorar a legibilidade. A indentação consistente também é crucial para entender a estrutura do código.
3. O Comando else
O else complementa o if, definindo um bloco de código que será executado quando a condição do if for falsa.
if (expressão) {
// bloco se verdadeiro
} else {
// bloco se falso
}
Exemplo: determinar se um número é par ou ímpar.
#include <stdio.h>
int main() {
int numero = 7;
if (numero % 2 == 0) {
printf("%d é par.\n", numero);
} else {
printf("%d é ímpar.\n", numero);
}
return 0;
}
Um cuidado importante com o else é evitar o "else solto" — ou seja, um else que não está claramente associado a um if específico. Em estruturas aninhadas, o else sempre se liga ao if mais próximo que ainda não possui um else correspondente. O uso de chaves elimina essa ambiguidade.
4. Encadeamento com else if
Para testar múltiplas condições em sequência, utilizamos a estrutura if-else if-else:
if (condicao1) {
// bloco 1
} else if (condicao2) {
// bloco 2
} else if (condicao3) {
// bloco 3
} else {
// bloco padrão
}
Exemplo: classificar uma nota de 0 a 100 em conceitos A, B, C, D ou F.
#include <stdio.h>
int main() {
int nota = 85;
if (nota >= 90) {
printf("Conceito A\n");
} else if (nota >= 80) {
printf("Conceito B\n");
} else if (nota >= 70) {
printf("Conceito C\n");
} else if (nota >= 60) {
printf("Conceito D\n");
} else {
printf("Conceito F\n");
}
return 0;
}
Essa abordagem é mais eficiente e lógica do que usar múltiplos if independentes, pois assim que uma condição é satisfeita, as demais são ignoradas. Com if independentes, todas as condições seriam avaliadas desnecessariamente.
5. Operadores Relacionais e Lógicos em Condicionais
As condições dentro de if utilizam operadores relacionais e lógicos.
Operadores relacionais:
| Operador | Significado |
|---|---|
== |
igual a |
!= |
diferente de |
< |
menor que |
> |
maior que |
<= |
menor ou igual a |
>= |
maior ou igual a |
Operadores lógicos:
| Operador | Significado |
|---|---|
&& |
E lógico |
|| |
OU lógico |
! |
NÃO lógico |
Exemplo: validar se um número está no intervalo de 0 a 100.
#include <stdio.h>
int main() {
int valor = 50;
if (valor >= 0 && valor <= 100) {
printf("%d está no intervalo [0, 100].\n", valor);
} else {
printf("%d está fora do intervalo.\n", valor);
}
return 0;
}
A combinação de operadores permite criar condições complexas de forma clara e concisa.
6. O Comando switch
O switch é uma estrutura condicional alternativa, ideal para testar uma expressão contra múltiplos valores discretos.
switch (expressão) {
case valor1:
// código para valor1
break;
case valor2:
// código para valor2
break;
default:
// código padrão (opcional)
}
Exemplo: menu de opções.
#include <stdio.h>
int main() {
int opcao = 2;
switch (opcao) {
case 1:
printf("Opção 1 selecionada: Cadastro\n");
break;
case 2:
printf("Opção 2 selecionada: Consulta\n");
break;
case 3:
printf("Opção 3 selecionada: Relatório\n");
break;
default:
printf("Opção inválida\n");
}
return 0;
}
O comando break é fundamental: ele interrompe a execução do switch e sai da estrutura. Sem o break, ocorre o fenômeno de fall-through: a execução continua para o próximo case, independentemente do valor. Isso pode ser útil em alguns casos (como agrupar múltiplos valores), mas geralmente é fonte de bugs.
7. Diferenças entre if-else e switch
A escolha entre if-else e switch depende do contexto:
- Use
switchquando: a condição for baseada em uma única expressão que assume valores discretos (inteiros, caracteres ou enumerações). O código fica mais legível e organizado. - Use
if-elsequando: as condições envolverem intervalos numéricos, expressões complexas, operadores lógicos ou comparações com diferentes variáveis.
Limitações do switch em C:
- A expressão deve ser de tipo inteiro (int, char, enum) — não funciona com floats, strings ou ponteiros.
- Os valores dos case devem ser constantes em tempo de compilação.
- Não é possível testar intervalos diretamente (ex: case 1..5 não é válido).
Em termos de desempenho, o compilador pode otimizar um switch com muitos casos para uma tabela de desvio (jump table), tornando-o potencialmente mais rápido que uma cadeia de if-else. Contudo, para a maioria das aplicações, a diferença é irrelevante; a legibilidade deve ser o critério principal.
8. Boas Práticas e Armadilhas Comuns
Erro clássico: = no lugar de ==
// ERRADO: atribuição, não comparação
if (x = 5) {
printf("x é 5");
}
Esse código compila sem erros, mas atribui 5 a x e sempre entra no if, pois o resultado da atribuição (5) é diferente de zero. Sempre use == para comparação.
Uso de constantes simbólicas:
Em vez de números mágicos, defina constantes com #define ou enum para tornar o código mais legível e fácil de manter.
#define OPC_CADASTRO 1
#define OPC_CONSULTA 2
switch (opcao) {
case OPC_CADASTRO:
// ...
break;
case OPC_CONSULTA:
// ...
break;
}
Evite if aninhados profundos: mais de três níveis de aninhamento tornam o código difícil de ler. Considere refatorar com funções auxiliares ou reestruturar a lógica.
Sempre inclua o default no switch: mesmo que você acredite que todos os casos estão cobertos, o default captura valores inesperados e evita comportamentos silenciosos.
Dominar as estruturas condicionais é essencial para escrever código C claro, correto e eficiente. Pratique com exemplos variados e sempre questione qual estrutura melhor se adequa ao problema que você está resolvendo.
Referências
- Documentação oficial do GCC: Condicionais em C — Guia do compilador GCC sobre expressões condicionais e operadores.
- C Programming: Decision Making (if, if-else, switch) — Tutorial completo da Programiz sobre estruturas de decisão em C, com exemplos práticos.
- The C Programming Language (K&R) - Capítulo 3: Control Flow — Capítulo clássico do livro de Kernighan e Ritchie sobre fluxo de controle, incluindo if e switch.
- C If...Else Statement (w3schools) — Tutorial interativo da w3schools sobre condicionais if, else e else if em C.
- Switch Statement in C (GeeksforGeeks) — Artigo detalhado sobre o comando switch em C, incluindo fall-through e boas práticas.
- C Logical Operators (Tutorialspoint) — Explicação dos operadores lógicos &&, || e ! em C, com exemplos de uso em condicionais.
- Coding Style and Best Practices for Conditionals (Linux Kernel Style Guide) — Seção do guia de estilo do kernel Linux sobre formatação de if, else e switch.