Publicidade

Aula 17: Técnicas de Depuração

Como depurar programas em C, com cobertura prática de depuração com printf e bugs comuns.

📖 O que você vai aprender nesta página
✅ Essenciais que você precisa saber
  • Use printf para inspecionar valores
  • Preste atenção nos avisos: gcc -Wall -Wextra
  • Corrija os erros a partir do primeiro reportado
⭐ Leia se tiver tempo
  • Depuração interativa com gdb
  • Sanitizers (-fsanitize=address,undefined)
  • Análise estática (cppcheck, etc.)

O que é Depuração — A Arte de Encontrar e Corrigir Bugs

Quando um programa não funciona como esperado, depuração é o processo de encontrar e corrigir a causa. Por C ser uma linguagem compilada, os bugs se dividem em duas grandes categorias.
Erros de compilação
O código não compila por causa de erros de sintaxe. As mensagens do compilador são sua principal pista.
Bugs em tempo de execução
O código compila, mas produz resultados errados ou trava. Rastreie com depuração com printf.

Passos básicos de depuração

🔍
1. Reproduzir
Identifique quando o bug ocorre
📍
2. Localizar
Estreite o foco com printf
🤔
3. Hipotetizar
Pergunte por que está errado
🛠️
4. Corrigir e verificar
Retestar após corrigir
Importante: Não remende o ponto "provavelmente é aqui" — sempre confirme a causa raiz antes de corrigir. Correções por chute introduzem novos bugs.

Lendo Erros de Compilação

As mensagens de erro do gcc seguem o formato arquivo:linha:coluna: error: mensagem. A chave é corrigir o primeiro erro primeiro.

Erros de compilação comuns

error: expected ';' before '}' token
Causa: Falta um ponto e vírgula ;. Verifique a linha anterior à reportada.
int x = 10   // ← sem ; !
printf("%d", x);
error: 'pritnf' was not declared in this scope
Causa: Um nome de função escrito errado (pritnf → printf) ou um #include ausente.
error: 'x' undeclared (first use in this function)
Causa: A variável nunca foi declarada, ou está sendo usada fora de seu escopo.
warning: format '%d' expects argument of type 'int'
Causa: O especificador de formato não corresponde ao tipo do argumento — por exemplo, %d usado onde um double exigiria %f.
Dica: Não se assuste se vir uma lista longa de erros. Corrigir o primeiro costuma fazer vários outros sumirem de uma vez.

Depuração com printf — A Técnica Mais Simples

Use printf para imprimir valores de variáveis ou marcadores de "passei por aqui" e rastrear o comportamento do seu programa. É a técnica mais simples que iniciantes podem aplicar imediatamente.

Técnicas

// Técnica 1: imprimir valores de variáveis
printf("DEBUG: x=%d, y=%d\n", x, y);

// Técnica 2: verificar se a execução chegou até aqui
printf("DEBUG: cheguei antes do laço\n");

// Técnica 3: imprimir variáveis do laço a cada iteração
for (int i = 0; i < n; i++) {
  printf("DEBUG: i=%d, sum=%d\n", i, sum);
  sum += a[i];
}

// Técnica 4: ver qual ramo foi tomado
if (x > 0) {
  printf("DEBUG: x é positivo\n");
} else {
  printf("DEBUG: x é 0 ou negativo\n");
}

Experimente você mesmo

O código abaixo deveria calcular uma soma, mas um bug dá a resposta errada. Use a depuração com printf para encontrar a causa.
Dica: Olhe a saída DEBUG. Com que valor i começa? a[5] existe?

Padrões Comuns de Bugs

Conhecer os padrões de bugs em que iniciantes costumam cair vai deixar sua depuração muito mais rápida.
Erros de off-by-one
Limites de laço errados por um — começar em i=1 em vez de i=0, ou usar i<=n quando queria i<n.
// Errado: acessa a[5] (fora dos limites)
for (int i = 0; i <= 5; i++) sum += a[i];
// Certo:
for (int i = 0; i < 5; i++) sum += a[i];
Variáveis não inicializadas
Declarar uma variável sem inicializá-la a deixa com dados indeterminados (lixo).
int sum;       // ← valor inicial é lixo!
for (...) sum += a[i]; // lixo + a[i] = ?
// Certo: int sum = 0;
Confundir = com ==
if (x = 5) atribui 5 a x (e sempre é verdadeiro). Use == para comparação.
if (x = 5)  // Errado: atribui 5 a x (sempre verdadeiro)
if (x == 5) // Certo: verifica se x é igual a 5
Laços infinitos
A variável do laço nunca é atualizada, ou a condição é sempre verdadeira.
int i = 0;
while (i < 10) {
  printf("%d\n", i);
  // esqueceu do i++! -> i fica em 0 para sempre
}
& faltando no scanf
Deve ser scanf("%d", &x), não scanf("%d", x). Sem o endereço, o scanf quebra.
scanf("%d", x);   // Errado: crash!
scanf("%d", &x);  // Certo

Desafio de Correção de Bugs

O código abaixo contém três bugs. Corrija-os para que a saída seja exatamente average = 5.00.
Publicidade
← Aula anterior
Aula 16: Laços (for/while)
Próxima aula →
Aula 20: Arrays

Aulas relacionadas

Referência
Aula 33: Dicionário de Erros de Compilação
Catálogo de erros de compilação em C e como corrigi-los. Guia completo para ler mensagens do gcc.
Referência
Aula 34: Erros em Execução e Segfaults
Causas de segmentation faults em C e como corrigi-los. Guia completo de erros em tempo de execução.

Quiz

Confira seu entendimento.

Q1. Qual o propósito da depuração com printf?

Decorar a tela
Inspecionar valores de variáveis durante a execução
Tornar o programa mais rápido

Imprimir valores de variáveis ou marcadores de execução com printf ajuda a localizar a causa de um bug. É a técnica de depuração mais básica.

Q2. O que um depurador (como o gdb) pode fazer?

Corrigir o código automaticamente
Executar o código linha a linha e inspecionar variáveis
Acelerar a compilação

Depuradores permitem definir breakpoints, executar passo a passo e observar variáveis — tudo que você precisa para analisar um programa em detalhes.

Q3. Qual é um bom hábito para evitar bugs?

Escrever grandes quantidades de código de uma vez
Compilar e testar com frequência, em pequenos incrementos
Nunca escrever comentários

Escrever pequenos pedaços de código e testar com frequência permite pegar bugs rapidamente. Comentários também ajudam muito.

Compartilhe este artigo
Compartilhar no X Compartilhar no Facebook