Menu

Laço while em C++: sintaxe, do-while e armadilhas

O laço while do C++ explicado: o while que verifica a condição primeiro, o do-while que roda pelo menos uma vez, repetir até um valor sentinela, break e continue, e como evitar laços infinitos.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Quando você não tem um contador

O laço for é construído em torno de um contador que você define de antemão. Mas muitos laços não têm uma contagem clara: continuar lendo números até a entrada acabar, continuar pedindo uma senha até ela estar correta, continuar dividindo um valor pela metade até chegar a 1. Para esses casos, o laço while se encaixa naturalmente: ele simplesmente repete enquanto uma condição continuar verdadeira.

Um laço while verifica a condição antes de cada passagem, inclusive a primeira. Se a condição já começar falsa, o corpo nunca roda.

A condição count > 0 é verificada primeiro; se for verdadeira, o corpo roda, depois voltamos e verificamos de novo. A linha count-- é o que acaba tornando a condição falsa: tire-a e o laço roda para sempre.

A anatomia de um laço while

Compare-o com o laço for de três partes que você já conhece. Um laço while separa essas três tarefas: você faz a inicialização antes do laço, a condição vai entre os parênteses e a atualização fica dentro do corpo.

int i = 0;          // inicialização - antes do laço
while (i < 5) {     // condição - verificada a cada passagem
    cout << i << "\n";
    i++;            // atualização - você precisa lembrar dela por conta própria
}

Essa última parte é a pegadinha. Em um laço for a atualização fica logo ao lado da condição, então é difícil esquecer. Em um laço while ela é só mais uma instrução no corpo: o erro mais comum é deixá-la de fora e travar o programa.

Uma armadilha do C++ que pega os iniciantes: um ponto e vírgula perdido logo depois da condição transforma o corpo em uma instrução vazia.

int i = 0;
while (i < 5);   // <-- este ponto e vírgula é todo o corpo do laço
{
    cout << i << "\n";
    i++;
}

Isso roda para sempre sem fazer nada, porque o ; é o corpo e i nunca muda. O bloco entre chaves então roda exatamente uma vez. O compilador não vai te impedir: é código perfeitamente legal, só não é o que você quis dizer.

do-while: rodar o corpo pelo menos uma vez

Às vezes você precisa que o corpo rode uma vez antes de poder sequer decidir se vai repetir. O laço do-while verifica a condição no final, então o corpo sempre executa pelo menos uma vez:

Você precisa pedir e ler pelo menos uma vez antes de saber se a entrada é válida, que é exatamente o que o do-while te dá. Repare no ponto e vírgula depois de while (...): em C++ ele é obrigatório para do-while, e esquecê-lo é um erro de compilação frequente.

A diferença para um while comum aparece claramente quando a condição já começa falsa:

do-while body é impresso. O laço while pula o corpo por completo porque x < 5 era falso antes da primeira verificação.

Repetir até cin falhar

Um uso clássico do while é ler até a entrada parar: não há contador, você simplesmente continua até o fluxo dizer para parar. Em C++, cin >> value é avaliado como o próprio fluxo, que é verdadeiro enquanto a leitura tem sucesso e falso assim que chega ao fim da entrada ou a um tipo que não combina. Isso o torna uma condição de laço limpa:

A condição cumpre dois papéis: ela lê e testa em um único passo. Compare isso com um valor sentinela, digamos, parar ao receber 0. Aí você precisa ler uma vez antes do laço e de novo no final de cada passagem para que a condição sempre teste uma entrada nova:

Se você esquecer a segunda leitura dentro do corpo, value nunca muda e você tem um laço infinito. A forma while (cin >> value) contorna isso ao embutir a leitura na condição.

break e continue em laços while

break e continue funcionam aqui igual a um laço for. break sai do laço imediatamente; continue pula direto para a verificação da condição, ignorando o resto da passagem atual:

Isso imprime 1 3 5 7 9. O while (true) deliberadamente nunca para sozinho: o break é a única saída. Cuidado com continue em um laço while: como a atualização faz parte do corpo, pular de volta ao topo com continue antes de ter avançado o contador é uma forma silenciosa de travar o laço. No exemplo acima n++ roda primeiro, então é seguro.

Cuidado com os laços infinitos

A condição precisa acabar se tornando falsa, e isso depende inteiramente de algo dentro do corpo mudar. Os dois culpados habituais são esquecer a atualização e atualizar de um jeito que pula o valor de saída:

int i = 0;
while (i < 5) {
    cout << i << "\n";   // i nunca muda -> roda para sempre
}
int i = 0;
while (i != 10) {
    i += 3;   // 0, 3, 6, 9, 12... passa direto pelo 10 -> roda para sempre
}

O primeiro trava porque i nunca é atualizado. O segundo trava porque o contador passa por cima do valor exato que a condição procura: prefira < ou <= em vez de != quando o passo pode não cair certinho. Um while (true) é aceitável se tiver um break garantido; um acidental é só um bug. E lembre da armadilha do corpo vazio while (...); de antes: um ponto e vírgula fora de lugar produz um laço infinito que parece correto à primeira vista.

A seguir: o laço for baseado em intervalo

Um laço while é a ferramenta certa quando você repete até uma condição mudar e não há uma contagem clara. Mas quando você só quer percorrer todos os elementos de um contêiner (um vector, um array, uma string) sem um índice nem uma condição para gerenciar, o C++ moderno tem algo mais limpo: o laço for baseado em intervalo (for (auto x : container)). É o assunto da próxima página.

Perguntas frequentes

Qual é a diferença entre while e do-while em C++?

Um laço while verifica a condição antes da primeira passagem, então o corpo pode rodar zero vezes. Um laço do-while roda o corpo uma vez primeiro e só depois verifica a condição no final, então ele sempre roda pelo menos uma vez. Use do-while quando o trabalho precisar acontecer antes de você decidir se vai repetir, como pedir uma entrada e então validá-la. Note que do-while precisa de ponto e vírgula depois do while (...) final.

Quando devo usar um laço while em vez de um for em C++?

Use um laço while quando você não tem um contador claro e só quer repetir até alguma condição mudar: ler entrada até cin falhar, consultar até um valor estar pronto ou processar uma fila até ela esvaziar. Recorra a um laço for quando souber a quantidade de iterações ou tiver um índice óbvio para contar.

Como parar um laço while infinito em C++?

Garanta que algo dentro do corpo acabe tornando a condição falsa (decrementar um contador, avançar um ponteiro, ligar uma flag). Para um laço while (true) intencional, coloque um break dentro protegido por um if. Se um laço travar, a causa habitual é esquecer de atualizar a variável da qual a condição depende.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR