Menu

break e continue em C: como funcionam e quando usar

break sai de um laço ou de um switch; continue pula para a próxima passagem. Como cada um se comporta em for, while e do-while, como escapar de laços aninhados com uma flag ou goto, e os usos indevidos que deixam laços difíceis de acompanhar.

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

Duas formas de mudar o fluxo de um laço

A condição de um laço decide quando ele termina, mas às vezes a resposta de verdade aparece no meio do corpo. Você está buscando em um array e encontra o item no terceiro elemento - por que verificar os outros 997? Ou você está processando uma lista e uma entrada está em branco - pule e siga adiante.

C tem uma palavra-chave para cada caso:

  • break - saia do laço agora. A execução continua na primeira instrução depois dele.
  • continue - abandone apenas esta passagem. Siga para a próxima.

O primeiro laço imprime 1 2 3 4 e para. O segundo imprime 1 2 3 4 6 7 8 9 10 - ele pulou um valor e seguiu em frente.

break em um laço

O uso canônico é uma busca que para assim que dá certo:

Como found é definido antes do break, o código depois do laço consegue distinguir entre "encontrei" e "acabaram os elementos". Esse par - uma variável de resultado mais um break - é o idioma padrão de busca em C. O próprio contador do laço não é utilizável depois quando é declarado no cabeçalho, já que sai de escopo na chave de fechamento.

break sempre sai de um laço: o for, while, do-while ou switch mais próximo que o envolve.

continue em um laço

continue serve para entradas que devem ser puladas em vez de interromper o trabalho:

Para onde o continue salta depende do laço:

for        -> a parte de atualização do cabeçalho (então o contador ainda avança)
while      -> o teste da condição (nada mais no corpo executa)
do-while   -> o teste da condição lá embaixo

Essa diferença não é acadêmica. Em um laço for, o continue nunca consegue pular o incremento do contador, porque o incremento está no cabeçalho. Em um while, consegue:

/* BUG: continue pula i++, então isto trava no primeiro número par */
int i = 0;
while (i < 10) {
    if (i % 2 == 0) {
        continue;
    }
    printf("%d ", i);
    i++;
}

Ou mova i++ para antes do continue, ou escreva como um laço for, em que o cabeçalho torna impossível errar.

break em um switch não é um break no laço

break encerra o laço ou o switch mais próximo que o envolve - o que estiver mais perto. Coloque um switch dentro de um laço e todo break nele pertence ao switch:

O comando q imprime sua mensagem e o laço continua rodando pelos cc. Se sair era para encerrar o laço, aquele break não fez isso. As soluções são uma flag, um goto, ou mover o laço para dentro de uma função e usar return - todas mostradas abaixo.

Escapando de laços aninhados

Um único break sai de um nível. Dentro de dois laços aninhados ele só encerra o interno, e o laço externo começa sua próxima passagem como se nada tivesse acontecido.

C não tem break 2 nem break rotulado. Três opções honestas:

Uma flag. Portável, óbvia e um pouco ruidosa:

A flag aparece em dois lugares - a condição externa e a atribuição - e esse é o custo. Com três níveis de aninhamento fica genuinamente desagradável.

goto. O tão difamado salto do C, e este é o caso em que programadores C experientes o usam sem pedir desculpas:

Um goto para frente, para um rótulo logo depois dos laços, faz exatamente o que um break rotulado faria em outras linguagens, em uma linha e sem flag alguma para manter sincronizada. A reputação que o goto tem é merecida por saltos para trás e saltos para o meio de outros blocos, que produzem de fato um fluxo de controle ilegível. Um único salto para frente saindo de laços aninhados não é isso. O kernel Linux usa o mesmo padrão em caminhos de limpeza. Use-o de forma deliberada e parcimoniosa; não deixe o tabu te empurrar para uma alternativa de três flags que é mais difícil de ler.

Uma função e return. Geralmente a melhor resposta, porque uma busca merece um nome:

return desmonta todos os laços da função, não precisa de flag nem de rótulo, e o código de busca agora tem um nome e pode ser testado sozinho. Quando o aninhamento é profundo o bastante para que escapar dele seja um problema, isso é muitas vezes uma pista de que o bloco queria mesmo ser uma função.

Quando ajudam e quando atrapalham

break e continue justificam seu lugar quando deixam um laço dizer "este caso está resolvido" uma vez, perto do topo, em vez de embrulhar o corpo inteiro em um if. Compare:

/* com continue: o trabalho de verdade não fica indentado */
for (int i = 0; i < n; i++) {
    if (!isValid(a[i])) continue;
    if (isDuplicate(a[i])) continue;
    process(a[i]);
}

/* sem: cada guarda adiciona um nível */
for (int i = 0; i < n; i++) {
    if (isValid(a[i])) {
        if (!isDuplicate(a[i])) {
            process(a[i]);
        }
    }
}

Eles atrapalham quando são muitos. Um laço com cinco breaks espalhados e três continues tem uma condição de saída que não existe escrita em lugar nenhum - o leitor precisa simular o corpo inteiro para saber quando ele para. Duas diretrizes que se sustentam bem: mantenha as guardas com continue juntas no topo do corpo, e se um laço tem mais de um ou dois breaks, considere se a condição do cabeçalho não deveria estar fazendo esse trabalho.

Duas armadilhas menores. continue em um do-while salta para o teste lá embaixo, que é a próxima coisa de qualquer jeito - inofensivo, mas surpreende as pessoas. E break fora de qualquer laço ou switch é um erro de compilação, que é o único engano aqui que o compilador pega para você.

Perguntas frequentes

Qual é a diferença entre break e continue em C?

break encerra o laço por completo e a execução continua depois dele. continue abandona apenas a passagem atual e segue para a próxima - para a atualização em um laço for, ou direto para o teste da condição em um while ou do-while.

Como saio de um laço aninhado em C?

Um único break só sai do laço mais interno. Para sair dos dois, ou você define uma flag e a testa na condição do laço externo, ou usa goto para saltar para um rótulo depois dos laços, ou - geralmente o mais limpo - move os laços para dentro de uma função e usa return.

O break sai do laço ou apenas do switch?

Do que o envolve mais de perto. Um break dentro de um switch que está dentro de um laço encerra apenas o switch; o laço continua. Para sair do laço de dentro de um switch você precisa de uma flag, um goto ou um return.

Por que continue causa um laço infinito no meu while?

Porque continue salta para a condição e pula o resto do corpo - incluindo o incremento do contador, se ele estiver no fim. Em um laço for a atualização fica no cabeçalho, então sempre executa; em um while, mova a atualização para antes do continue ou use um for.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR