Estruturas de Repetição

Atualizado pela última vez em setembro de 2021.

As linguagens normalmente oferecem mais de um comando de repetição; C++ oferece quatro (três nomes para quatro comandos). Uma coisa importante a se aprender é escolher um comando para a repetição.

Dicas gerais

Alguns dos problemas mais comuns nas repetições de quem ainda está aprendendo é escrever o mesmo teste (ou testes opostos) duas ou mais vezes. Como em várias outras situações de programação, se você precisou escrever a mesma coisa várias vezes, é sinal de que seu programa pode ser simplificado.

Outro problema comum é abusar dos seletores dentro das repetições. Os seletores são instruções bem lentas nos computadores modernos, é bom aprender a ter cuidado com eles desde o início da aprendizagem. Dentro de uma repetição, um mesmo seletor pode ter que ser executado centenas ou milhares de vezes, produzindo lentidão significativa. Se você coloca um seletor dentro de uma repetição para que algum comando seja executado uma única vez durante a repetição, então é sinal de que esse comando não deveria estar na repetição. Fora da repetição esse comando será realizado uma única vez sem a necessidade de um seletor. Se for para realizar algo na primeira vez, coloque o comando antes da repetição e faça uma repetição para os outros casos. Se for para fazer alguma coisa na última vez, coloque o comando depois da repetição e deixe a repetição apenas para os primeiros itens.

Às vezes vale a pena repetir um comando dentro e fora da repetição para produzir uma repetição simples e fácil de corrigir quando for necessário. Isso deve evitar a necessidade de colocar um seletor dentro da repetição e também deve evitar a necessidade de criar um valor válido temporário apenas para o teste que controla a repetição permitir a primeira execução. Mais adiante, na seção de exemplos, isso está apresentado em código fonte.

O controle da repetição costuma exigir variáveis auxiliares que dificultam a legibilidade, portanto, fique atento à quantidade de variáveis auxiliares, excesso de variáveis auxiliares indica necessidade de simplificação do seu programa. O uso de variáveis booleanas ajuda a manter o programa mais legível com menos operadores nos testes.

Para fins de legibilidade e organização, exigimos que as repetições tenham um fluxo simples e bem definido de instruções, ou seja, sem instruções para terminar antes da hora, ou para voltar ao começo da repetição. É importante praticar a habilidade de desenvolver controles simples e legíveis. Isso geralmente requer atenção ao teste da repetição: necessidade de criar exceções ao fluxo da repetição indicam que o seu teste deveria ser mais sofisticado.

O while

O comando while é o primeiro ensinado e o mais versátil. Qualquer repetição pode ser implementada com o while, por isso é importante saber usá-lo. A repetição do while é controlada por um teste e por isso é importante aprender a planejar quais elementos de controle devem ser colocados no programa para que um teste controle a repetição. Em vários exercícios existe a restrição de obrigatoriedade em se resolver o problema usando o while. Apesar de eu não concordar com etapa de uso obrigatório do while no curso, eu reconheço a importância dela na fixação de conteúdo, para que todos saibam usar esse comando quando for a melhor escolha. Se você chegou no curso já sabendo programar, fique atento a esta etapa do curso, nem sempre é permitido usar outros comandos.

Ao usar o while, esteja atento à repetição zero vezes: Faz sentido repetir zero vezes? Alguma coisa inesperada acontece se a repetição for realizada zero vezes?

O do-while

O comando do-while também é controlado por teste, mas ao contrário do while, ele repete uma ou mais vezes. Se o problema faz sentido com repetição zero vezes, então o do-while não deve ser usado. Se não faz sentido repetir zero vezes, então ele pode ser mais apropriado que o while.

O for (controlado por teste)

Existem dois comandos for no C++. Estamos falando aqui daquele que tem o formato for (inicialização; teste; atualização) comando. Esse comando é essencialmente o comando while com pedaços escritos em locais específicos. Ele tem duas vantagens sobre o while:

  1. Ao colocar os comandos de inicialização, teste e atualização todos juntos, facilita o entendimento a respeito de como o teste é controlado
  2. Ao permitir a declaração de variáveis dentro da seção de inicialização, facilita a criação de variáveis auxiliares que existem somente na repetição.

Se não for para se aproveitar dessas características do for, prefira usam um while. É muito confuso ler um for, achar que entendeu o controle e mais para frente encontrar outras instruções que modificam o controle da repetição. Se uma variável de controle da repetição precisa continuar existindo depois da repetição, pode ser melhor usar um while.

O for (controlado por estrutura de dados)

Existem dois comandos for no C++. Estamos falando aqui daquele que tem o formato for (variável: estrutura) comando. Esse comando é usado para processar todos os itens de uma estrutura de dados. Ele foi criado para ser usado com uma variável local, seguindo o princípio da localidade de variáveis, ou seja, a variável usada para iterar é declarada dentro do for e só existe no for. Porém, na revisão de 2014 a linguagem C++ foi alterada para permitir o uso de uma variável externa (declarada fora do for). O uso de variável externa favorece a interrupção prematura da repetição, mantendo o estado da variável após a repetição. Porém, isso prejudica a legibilidade e deve ser evitado enquanto você está aprendendo a programar. Se a sua repetição deve acabar antes de processar todos os elementos, é preferível usar um while ou a forma anterior do for. Se a sua repetição precisa analisar todos os elementos, mesmo que seja para aprofundar o processamento só com alguns deles, então essa forma é preferível.

Essa forma deve ser preferencialmente usada com vetores do tipo vector mas pode ser usada com vetores do tipo da linguagem C, desde que o tamanho do vetor seja igual à sua capacidade, pois com esse tipo de vetor a repetição será feita com toda a sua capacidade.

Exemplos

Abuso de seletores dentro de uma repetição (note que o mesmo teste é feito duas vezes a cada iteração, além de que existe a necessidade de uma inicialização sem sentido só para o controle da repetição):

Com abuso de seletores

int a = 0; while (a >= 0) { cin >> a; if (a >= 0) { ... } }

O código fica mais eficiente sem repetir seletores (repetindo o comando de leitura):

Sem abuso de seletores

int a; cin >> a; while (a >= 0) { ... cin >> a; }

Esta página é mantida por Bruno Schneider para a disciplina de IAlg