Programação I

Erros frequentes em C

Existe 2 tipos de erros em programação:

  1. erros de compilação
  2. erros de execução

Os erros de compilação ocorrem quando o programa que escrevemos não obedece às regras da linguagem. Este tipo de erros são normalmente fáceis de detectar. Os mais frequentes são:

  1. Esquecer um ponto e vírgula.
  2. Esquecer de fechar uma chaveta.
  3. Esquecer de fechar as aspas num printf ou scanf.
  4. Esquecer de fechar um comentário.
  5. Esquecer a declaração de variáveis.
  6. Escrever mal uma palavra (ex: studio.h em vez de stdio.h)

Os erros de execução são mais subtis. O programa compila normalmente sem erros, mas ao ser executado não faz aquilo que estamos à espera que faça. Na gíria informática, denominamos este tipo de erros por bugs.

Muitos principiantes em programação ficam frustrados quando não conseguem detectar os bugs. Com a experiência, vão ver que começam a detectá-los com rapidez. O importante é não entrarem em pânico.

Para se detectar um bug, devem tentar isolar o erro. Isso pode ser feito utilizando printfs no meio do código para ver o que é que o programa está a fazer passo a passo. Em alternativa, existem programas especiais denominados de debuggers que permitem executar o programa passo a passo e ver o conteudo das variáveis do programa.

De seguida, apresenta-se alguns bugs clássicos que ocorrem em C. São clássicos porque não existe nenhum programador de C que nunca os tenha feito. Tenho a certeza que mais tarde ou mais cedo todos vós também vão cometer (ou já cometeram) estes erros.

  1. Esquecer de inicializar variáveis
  2. Esquecer o & no scanf
  3. Não colocar as flags correctas (%d,%c,%f,...) no printf ou scanf
  4. Utilizar = em vez de ==
  5. Ciclo infinito
  6. Ponto e vírgula no lugar errado
  7. Não agrupar instruções quando se pretende uma instrução composta

1. Esquecer de inicializar variáveis

Exemplo:

       int i, soma;

       i = 1;
       while (i < 10)
        {
          soma = soma + i;
          i++;
        }
       ...

A variável soma não está inicializada.

2. Esquecer o & no scanf

Exemplo:

       ...
       printf("Introduza um número: ");
       scanf("%d", x);
       ...

em vez de:

       ...
       printf("Introduza um número: ");
       scanf("%d", &x);
       ...

3. Não colocar as flags correctas (%d,%c,%f,...) no printf ou scanf

Ditto.

4. Utilizar = em vez de == em comparações

Exemplo:

       if( i = 3 ) 
        {
          ...
        }

em vez de:

       if( i == 3 ) 
        {
          ...
        }

5. Ciclo infinito

Um ciclo cuja condição de paragem nunca é verificada. Isto acontece muito quando nos esqueçemos de actualizar um contador que controla a condição de paragem do ciclo. Exemplo:

       i = 1; s = 0; v = 0;
       while( i <= 100 )
        {
           s = s + i;
           v = v + i*i;
        }
       printf("%d %d\n", s, v);

6. Ponto e vírgula no lugar errado

Exemplo:

       i = 1; s = 0; v = 0;
       while( i <= 100 );
        {
           s = s + i;
           v = v + i*i;
           i++;
        }
       printf("%d %d\n", s, v);

O problema é o ponto-e-vírgula a seguir ao while. O código vai dar origem a um ciclo infinito visto que o corpo do while é a instrução vazia. O programa anterior é equivalente a:

       i = 1; s = 0; v = 0;
       while( i <= 100 )
         ;
       s = s + i;
       v = v + i*i;
       i++;
       printf("%d %d\n", s, v);

Este erro é tão frequente que alguns programadores acabam por adoptar outra regra nas chavetas:

       i = 1; s = 0; v = 0;
       while( i <= 100 ) {
          s = s + i;
          v = v + i*i;
          i++;
       }
       printf("%d %d\n", s, v);

Assim, torna-se menos provavel que um programador coloque o ponto-e-vírgula fora do sítio. Visualmente, a chaveta a abrir dá uma indicação que a instrução while está por completar.

O mesmo tipo de erro ocorre com a instrução if e for. Exemplo:

       if( i > 0 );
         printf("olá");
       printf("Até logo!");

Para o compilador, este código é equivalente a:

       if( i > 0 )
          ;
       printf("olá");
       printf("Até logo!");

Isto é, caso a condição (i>0) seja verdadeira, o computador irá executar a instrução vazia. As instruções seguintes serão executadas incodicionalmente, quer a condição seja verdadeira quer seja falsa.

7. Não agrupar instruções quando se pretende uma instrução composta

Exemplo:

     if(...)
       instrução1
       instrução2

Para o compilador, isto é equivalente a,

     if(...)
       instrução1
     instrução2

e provavelmente aquilo que queriam fazer era,

     if(...)
      {
        instrução1
        instrução2
      }