Subsecções


15 Outras Estruturas de Repetição

A linguagem C possui outras estruturas de repetição além do while (seção 14.1). São elas o for e o do...while.


15.1 A Estrutura de Repetição for

Considere o laço while abaixo:

  int i;

  i = 0; /* valor inicial da variável de controle da repetição */
  while (i  <= 10) /* Testa variável de  controle para saber  se haverá
                      repetição ou não do corpo do "while" */
  {
      .... 
      .... 

      i += 1; /* expressão de incremento da variável de controle da
                 repetição */
  }

Este laço pode ser expresso de forma diferente utilizando a estrutura de repetição for. A estrutura acima pode ser expressa de forma equivlente com um for da seguinte forma:

  int i;

  for (i = 0; i <= 10; i += 1)
  {
      .... 
      .... 
  }

Como pode-se observar, há 4 partes no laço for: inicialização, expressão de teste, expressão de incremento e o corpo do laço. O formato do laço for é:

corpo da repetição

}

A inicialização é executada uma única vez no início do laço. A expressão teste é então avaliada para verificar se o laço deve terminar. Caso a expressão seja verdadeira (isto é, diferente de Zero), o corpo da repetição é executado. Depois desta execução, a expressão de incremento é executada e o processo é repetido a partir da expressão teste. O corpo da repetição, por sua vez, pode ser uma sentença simples ou composta.

\includegraphics[scale=1.0]{for}

Veja abaixo um exemplo simples do laço for:

             int contador;

             for( contador = 0; contador < 5; contador += 1 )
                 printf( "contador = %d\n", contador );

             printf{"ACABOU !!!!\n");
Saída do programa:
             contador = 0
             contador = 1
             contador = 2
             contador = 3
             contador = 4
             ACABOU !!!!

Se você examinar cuidadosamente este exemplo, poderá ver precisamente o que está acontecendo. Primeiro, a inicialização é executada, que é a sentença contador = 0. Isso modifica o valor da variável contador para 0. Então, o teste é executado. como 0 < 5 é verdadeiro, o laço continua. Assim, o corpo da repetição é executado, imprimindo a primeira linha da saída, contador = 0. Depois disso, o incremento é executado, que é a sentença contador++, que altera o valor da variável contador para 1.

Esta é a 1ª iteração do laço. Então, o teste é executado novamente (como 1 < 5 é verdadeiro, o laço continua), o corpo da repetição mostra contador = 1, e contador é incrementado novamente.

Este processo continua até que contador seja 4 e contador = 4 seja impresso. Depois disso, contador é incrementado para 5 e o teste é executado. Mas desta vez, 5 < 5 é falso, então o laço não continua. A execução do programa continua na sentença que segue o laço (no caso, imprimir a frase ACABOU !!!).

Após a execução do laço, a variável contador tem valor 5.

Ao invés de usar o teste contador < 5, você poderia também ter usado a expressão contador <= 4. O resultado seria o mesmo. Use a expressão que você preferir. Outra expressão que também poderia ter sido usada é contador != 5. Porém esta expressão torna o programa menos legível (não é tão evidente que o valor de contador está sendo incrementado até atingir o valor 5). Além disso, isso poderia causar problemas se mudássemos a inicialização para um valor maior que 5. Por exemplo, se a inicialização for contador = 25 e a expressão teste for contador != 5 o laço nunca terminaria, pois o contador começa com 25 e a cada iteração o valor é incrementado, o que nunca tornaria o teste falso.

Também poderíamos ao invés de usar contador += 1 como a expressão de incremento, usar ++contador, contador++ e contador = contador + 1. O resultado seria o mesmo (neste caso, o uso de pós- e pré-incremento não faz diferença).

Se você quisesse incrementos de dois, você poderia escrever contador += 2 (ou contador = contador + 2).

15.1.1 Diversas sentenças dentro de um laço

Como no comando while, o corpo da repetição pode ser definido por uma sentença simples ou composta. No caso de uma sentença composta (bloco), não se deve esquecer de usar as chaves ({ e }) para delimitar o bloco da sentença composta.

Em um for também podemos ter mais de uma expressão de inicialização ou incremento. Nestes caso, elas devem ser separadas por vírgula (,) o que é ilustrado no exemplo abaixo:

Exemplo 1:

#include <stdio.h>

#include <stdio.h>

main( void ){
  
  int contador, total;
  
  for( contador = 0, total = 0; contador < 10; contador += 1 ) {
    total += contador;
    printf( "contador = %d, total = %d\n", contador, total );
  }
}

Saída:

    contador = 0, total = 0
    contador = 1, total = 1
    contador = 2, total = 3
    contador = 3, total = 6
    contador = 4, total = 10
    contador = 5, total = 15
    contador = 6, total = 21
    contador = 7, total = 28
    contador = 8, total = 36
    contador = 9, total = 45

No exemplo acima, contador = 0, total = 0 é a inicialização, contador < 10 é a expressão teste, e contador += 1 é a expressão de incremento.

Exemplo 2:

Um programa que imprime todos os números entre 30 e 5 (nesta ordem) divisíveis por 3, e no final imprime sua soma.

#include <stdio.h>

main( ){

  int i, soma;
  
  soma = 0;
  for( i = 30; i >= 5; i -= 1 ){
    if( (i % 3) == 0 ){
      printf( "\t%2d\n", i );
      soma += i;
    }
  }
  printf( "\t soma = %d\n", soma );
}

Saída do programa:

       30
       27
       24
       21
       18
       15
       12
        9
        6
       soma = 162

15.2 Usando while e for

Embora qualquer laço possa ser escrito usando while ou for, a escolha é baseada principalmente no estilo. Por exemplo, se o laço precisa de uma inicialização e um incremento, então o for geralmente é usado. No caso em que o número de repetições não é pré-determinado em geral usa-se o while.

Como o comando for:

   for( inicializacao; teste; incremento )
     sentenca;

é equivalente a:

   inicializacao;
   while( teste ) {
      sentenca;
      incremento;
   };

você pode escolher o que preferir, a princípio.


15.3 A Estrutura de Repetição do...while

Há outro comando de repetição em linguagem C . O do...while é bastante parecido com while, com a diferença que a expressão de teste é avaliada DEPOIS que o corpo da repetição é executado.

O formato do do...while é:

do

corpo da repetição

while (expressão teste)

\includegraphics[scale=1.0]{do-while}

O exemplo abaixo usa o do...while:

             int contador = 0;

             do {
                printf( "contador = %d\n", contador );
                contador += 1;
             } while( contador < 5 );

             printf("ACABOU !!!!\n");

A execução deste programa é idêntico ao primeiro exemplo mostrado para o comando while, com a expressão de teste mudada para o final.

Saída:

             contador = 0
             contador = 1
             contador = 2
             contador = 3
             contador = 4
             ACABOU !!!!

O do...while é usado quando o corpo da repetição deve ser executado pelo menos uma vez. Um exemplo comum disto é o processamento da entrada de um programa.

Exemplo 3:

Neste exemplo, o teste do laço é baseado no valor digitado pelo usuário. O laço deve ser executado pelo uma vez antes que o teste sobre o valor seja executado.

#include <stdio>

main( ){
  
  int num;
  
  printf( "Entre com um numero par:\n" );
  
  do{
    scanf( "%d", &num );
  } while( num % 2 != 0 );
  
  printf( "Obrigado.\n" );
}

Exemplo de execução:

     Entre com um numero par:
     3
     1
     5
     4
     Obrigado.

Neste caso, o valor da variável num é digitado pelo usuário. Depois disso, o teste é executado para verificar se o número é par (o teste num % 2 != 0 é falso se num é par já que o resto da divisão de qualquer número par por 2 é zero).

É possível escrever o programa acima usando while:

#include <stdio>

main( ){
  
  int num;      /* Atribui um numero impar a  num */
  
  printf( "Entre com um numero par:\n" );
  
  num = 1;
  while( num % 2 != 0 ){
    scanf( "%d", &num );
  }
  printf( "Obrigado.\n" );
}

O problema com este programa é que a variável num deve ser inicializada com um valor que torne o teste do laço verdadeiro. Neste exemplo, é simples encontrar tal valor. Para uma expressão teste mais complicada, isso pode não ser tão fácil.

Armando Luiz Nicolini Delgado
2013-10-21