C++ break e continue

Um laço normalmente vai até o fim: dá todas as voltas, e cada volta roda o corpo inteiro. Às vezes você quer interromper esse ritmo. Achou o que procurava? Não precisa olhar o resto: break ("quebrar") sai do laço na hora. Este item não interessa? continue ("continuar") pula o resto desta volta e passa para a próxima.

Você vai aprender
  • Como usar break para parar uma busca assim que achar o item.
  • Como escrever um laço "infinito de propósito" com while (true) e sair dele com break.
  • Como usar continue para pular itens.
  • A armadilha do break dentro de um switch (ele não sai do laço).
  • Como sair de dois laços, um dentro do outro, de uma vez.
  • Os erros reais: break fora de laço e continue que trava o while.

Os programas foram compilados com o g++ 15 na máquina fictícia da Ana, na pasta ~/cpp, com g++ -std=c++23 -Wall -Wextra arquivo.cpp -o programa. Vários exemplos usam a lista de compras da Ana, um std::vector<std::string> percorrido com o for de intervalo.


A ideia: procurar as chaves e pular as gavetas vazias

Você perdeu as chaves e vai abrir as gavetas da cozinha, uma por uma.

  • Achou as chaves na terceira gaveta? Você para de procurar. Ninguém abre as outras sete "só para terminar". Isso é o break: sai do laço inteiro.
  • Abriu uma gaveta e viu que ela está vazia? Não precisa revirar nada: fecha e passa para a próxima. Isso é o continue: abandona só esta volta.
breakcontinue
O que interrompeO laço inteiroSó a volta atual
Para onde vaiPara a primeira linha depois do laçoPara a próxima volta (no for, passa pelo passo antes)
Na gaveta"Achei! Parei de procurar.""Vazia, próxima."

1. break: parar quando achar

A Ana quer saber se café está na lista de compras. O programa mostra cada item que olha, para você ver onde a busca para:

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> lista = {"arroz", "feijão", "café", "leite", "pão"};
    std::string procurado = "café";
    for (const auto& item : lista) {
        std::cout << "Olhando: " << item << '\n';
        if (item == procurado) {
            std::cout << "Achei " << procurado << "!\n";
            break;
        }
    }
    std::cout << "Fim da busca.\n";
}
if (item == procurado)
A pergunta de cada volta: este item é o que eu procuro? (Comparar textos com == funciona com std::string, veja Strings.)
break;
Sai do laço imediatamente. O que restava do corpo e as voltas que faltavam são abandonados. O programa continua na linha depois da } do for.
$ g++ -std=c++23 -Wall -Wextra procurar.cpp -o procurar
$ ./procurar
Olhando: arroz
Olhando: feijão
Olhando: café
Achei café!
Fim da busca.

leite e pão nem foram olhados. Numa lista de 5 itens a economia é pequena; numa de 1 milhão, achar logo no começo e parar faz muita diferença.

O orçamento acabou

O break também serve para parar quando um limite é atingido. A Ana tem R$ 50 e vai comprando os itens na ordem da lista, até o próximo não caber mais no orçamento:

#include <iostream>
#include <vector>

int main() {
    std::vector<double> precos = {12.5, 8.0, 27.0, 15.0, 4.5};
    double orcamento = 50.0;
    double gasto = 0.0;
    int comprados = 0;
    for (double p : precos) {
        if (gasto + p > orcamento) {
            std::cout << "O próximo item (R$ " << p << ") estoura o orçamento.\n";
            break;
        }
        gasto += p;
        comprados++;
    }
    std::cout << "Itens comprados: " << comprados << ", gasto: R$ " << gasto << '\n';
}
$ g++ -std=c++23 -Wall -Wextra orcamento.cpp -o orcamento
$ ./orcamento
O próximo item (R$ 15) estoura o orçamento.
Itens comprados: 3, gasto: R$ 47.5

Repare na ordem dentro do corpo: primeiro o teste com break, depois a compra. Quando o break acontece, as linhas gasto += p; e comprados++; daquela volta não rodam: o item de R$ 15 não foi comprado.

Missão: percorra a lista e mostre o primeiro número que é múltiplo de 7 (n % 7 == 0, veja o resto da divisão), no formato Primeiro múltiplo de 7: 21. Use break para não mostrar o 35, que também é múltiplo.

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = {4, 10, 21, 35, 9};
    for (int n : numeros) {
        // teste aqui se n é múltiplo de 7

    }
}
#include <iostream>
#include <vector>

int main() {
    std::vector<int> numeros = {4, 10, 21, 35, 9};
    for (int n : numeros) {
        if (n % 7 == 0) {
            std::cout << "Primeiro múltiplo de 7: " << n << '\n';
            break;
        }
    }
}

2. while (true) + break: o laço com saída no meio

Na aula while, a soma até o usuário digitar 0 precisava ler o número antes do laço e de novo no fim do corpo. No do-while, o 0 acabava entrando na soma. Uma terceira forma, muito usada, é um laço que nunca para sozinho (while (true): "enquanto verdadeiro", ou seja, sempre) com uma saída no meio:

#include <iostream>

int main() {
    int soma = 0;
    while (true) {
        int numero = 0;
        std::cout << "Digite um número (0 para parar): ";
        std::cin >> numero;
        if (numero == 0) {
            break;
        }
        soma += numero;
    }
    std::cout << "Soma: " << soma << '\n';
}
$ g++ -std=c++23 -Wall -Wextra soma.cpp -o soma
$ ./soma
Digite um número (0 para parar): 10
Digite um número (0 para parar): 25
Digite um número (0 para parar): 7
Digite um número (0 para parar): 0
Soma: 42

O corpo lê o número uma vez só, a saída fica exatamente onde a decisão é tomada, e o 0 não entra na soma. A variável numero pode até nascer dentro do corpo, porque nenhuma condição de while precisa dela. O preço: quem lê o código precisa procurar o break para saber quando o laço termina. Por isso, use while (true) com uma saída clara, perto do começo do corpo.

Experimente: a entrada já vem pronta (10 25 7 0). Acrescente um contador quantos (crie-o fora do laço e some 1 depois do soma += numero;) e mostre também a média no fim. Depois troque a entrada por outros números, sempre terminando com 0.

#include <iostream>

int main() {
    int soma = 0;
    while (true) {
        int numero = 0;
        std::cout << "Digite um número (0 para parar): ";
        std::cin >> numero;
        if (numero == 0) {
            break;
        }
        soma += numero;
    }
    std::cout << "\nSoma: " << soma << '\n';
}

3. continue: pular para a próxima volta

Na lista da Ana, o que ela já comprou está marcado com # na frente. Para mostrar só o que falta, o programa pula os itens marcados:

#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> lista = {"arroz", "#leite", "feijão", "#pão", "café"};
    std::cout << "Ainda falta comprar:\n";
    for (const auto& item : lista) {
        if (item[0] == '#') {
            continue;
        }
        std::cout << "- " << item << '\n';
    }
}
item[0]
O primeiro caractere do texto (posição 0, veja Acessar Caracteres).
== '#'
É um #? Então o item já foi comprado.
continue;
Abandona o resto desta volta (o std::cout de baixo não roda) e vai direto para o próximo item.
$ g++ -std=c++23 -Wall -Wextra riscados.cpp -o riscados
$ ./riscados
Ainda falta comprar:
- arroz
- feijão
- café

O mesmo programa poderia ser escrito sem continue, com o std::cout dentro de um if (item[0] != '#'). Quando o corpo é curto, as duas formas são igualmente boas. O continue ganha quando o corpo é longo: os casos "descartáveis" saem logo no começo, e o resto do corpo não precisa ficar dentro de mais um par de chaves.

No for clássico: o passo ainda acontece

Num for (início; condição; passo), o continue pula o resto do corpo, mas o passo roda normalmente antes da próxima volta. Aqui ele pula os pares e mostra só os ímpares:

#include <iostream>

int main() {
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            continue;
        }
        std::cout << i << ' ';
    }
    std::cout << '\n';
}
$ g++ -std=c++23 -Wall -Wextra impares.cpp -o impares
$ ./impares
1 3 5 7 9 

Num while, porém, o passo é uma linha comum do corpo, e o continue pode pulá-lo. Isso trava o programa: veja o primeiro cenário de Quando dá errado.


4. A armadilha: break dentro de switch

O break tem dois empregos: sair de um laço e terminar um case do switch. Quando um switch está dentro de um laço, o break sai só do que estiver mais perto: o switch. Este menu tenta usar o break do case 0 para sair do while (true):

#include <iostream>

int main() {
    while (true) {
        int opcao = 0;
        std::cout << "1 - Olá   0 - Sair\nOpção: ";
        std::cin >> opcao;
        switch (opcao) {
            case 1:
                std::cout << "Olá!\n";
                break;
            case 0:
                std::cout << "Saindo...\n";
                break;
        }
    }
    std::cout << "Até logo!\n";
}
$ g++ -std=c++23 -Wall -Wextra menu.cpp -o menu
$ ./menu
1 - Olá   0 - Sair
Opção: 1
Olá!
1 - Olá   0 - Sair
Opção: 0
Saindo...
1 - Olá   0 - Sair
Opção: 0
Saindo...
1 - Olá   0 - Sair
Opção: ^C                « só o Ctrl+C resolveu
$ echo $?
130

O programa diz "Saindo..." e não sai. O break do case 0 terminou o switch, o corpo do while acabou, e o while (true) começou outra volta. O "Até logo!" nunca aparece. O compilador não avisa: o código é válido.

Há três consertos comuns:

  1. Uma variável de controle (flag, "bandeirinha"), que o case 0 liga e a condição do laço olha:
    #include <iostream>
    
    int main() {
        bool sair = false;
        while (!sair) {
            int opcao = 0;
            std::cout << "1 - Olá   0 - Sair\nOpção: ";
            std::cin >> opcao;
            switch (opcao) {
                case 1:
                    std::cout << "Olá!\n";
                    break;
                case 0:
                    sair = true;
                    break;
            }
        }
        std::cout << "Até logo!\n";
    }
    
    $ g++ -std=c++23 -Wall -Wextra menu2.cpp -o menu2
    $ ./menu2
    1 - Olá   0 - Sair
    Opção: 1
    Olá!
    1 - Olá   0 - Sair
    Opção: 0
    Até logo!
  2. Um do-while com a condição opcao != 0, como o menu da aula do-while.
  3. Trocar o switch por if/else if: aí o break dentro do if sai do laço, porque if não "captura" o break.

5. Sair de dois laços de uma vez

Quando há um laço dentro de outro (veja Laços Aninhados), o mesmo princípio vale: o break sai só do laço mais de dentro. A Ana quer arrumar 24 ovos numa bandeja retangular de até 9 × 9. Qual é o primeiro formato (linhas × colunas) que serve?

#include <iostream>

int main() {
    for (int linhas = 1; linhas <= 9; linhas++) {
        for (int colunas = 1; colunas <= 9; colunas++) {
            if (linhas * colunas == 24) {
                std::cout << "Bandeja " << linhas << " x " << colunas << '\n';
                break;
            }
        }
    }
    std::cout << "Fim\n";
}
$ g++ -std=c++23 -Wall -Wextra bandeja.cpp -o bandeja
$ ./bandeja
Bandeja 3 x 8
Bandeja 4 x 6
Bandeja 6 x 4
Bandeja 8 x 3
Fim

A ideia era parar no primeiro, mas o break só encerrou o laço das colunas. O laço das linhas seguiu para a linha 4, depois 5… e achou outros formatos. Para sair dos dois, há duas formas recomendadas.

Forma 1: uma variável de controle

#include <iostream>

int main() {
    bool achou = false;
    for (int linhas = 1; linhas <= 9 && !achou; linhas++) {
        for (int colunas = 1; colunas <= 9; colunas++) {
            if (linhas * colunas == 24) {
                std::cout << "Bandeja " << linhas << " x " << colunas << '\n';
                achou = true;
                break;
            }
        }
    }
    std::cout << "Fim\n";
}
$ g++ -std=c++23 -Wall -Wextra bandeja_flag.cpp -o bandeja_flag
$ ./bandeja_flag
Bandeja 3 x 8
Fim

O break sai do laço de dentro; a condição do laço de fora, linhas <= 9 && !achou ("e ainda não achou", veja Operadores Lógicos), fica falsa e encerra o de fora também.

Forma 2: uma função com return

O return sai da função inteira, não importa quantos laços existam lá dentro. Se a busca ficar numa função separada, ele resolve tudo de uma vez. Funções têm aula própria (Funções); por enquanto, leia void procurar_bandeja() { … } como "um bloco de código com nome, que o main chama":

#include <iostream>

void procurar_bandeja() {
    for (int linhas = 1; linhas <= 9; linhas++) {
        for (int colunas = 1; colunas <= 9; colunas++) {
            if (linhas * colunas == 24) {
                std::cout << "Bandeja " << linhas << " x " << colunas << '\n';
                return;
            }
        }
    }
    std::cout << "Nenhuma bandeja serve.\n";
}

int main() {
    procurar_bandeja();
    std::cout << "Fim\n";
}
$ g++ -std=c++23 -Wall -Wextra bandeja_funcao.cpp -o bandeja_funcao
$ ./bandeja_funcao
Bandeja 3 x 8
Fim

Quando a busca é a parte principal do trabalho, a função é a forma mais limpa: o nome procurar_bandeja já explica o que os laços fazem.

E o goto?

O C++ herdou do C o comando goto, que pula para um rótulo em qualquer ponto da função, e às vezes ele aparece em código antigo justamente para sair de laços aninhados. Este guia não o ensina: ele torna o caminho do programa difícil de seguir, e as duas formas acima resolvem o mesmo problema com clareza.


Qual usar?

SituaçãoFerramenta
Achei o que procurava; o resto não interessabreak
Repetir até uma condição que só se sabe no meio do corpowhile (true) + break
Este item não interessa, mas os próximos simcontinue (ou um if em volta do resto)
Sair do laço de dentro de um switchVariável de controle, do-while ou if/else if
Sair de dois laços aninhadosVariável de controle, ou função com return

Não exagere: um laço com três break e dois continue espalhados é difícil de entender. Se a condição de parada cabe naturalmente no while ou no for, deixe-a lá.


Quando dá errado

O programa trava (o continue pulou o passo do while)
#include <iostream>

int main() {
    int i = 0;
    std::cout << "Ímpares:" << std::endl;
    while (i < 10) {
        if (i % 2 == 0) {
            continue;
        }
        std::cout << i << ' ';
        i++;
    }
    std::cout << '\n';
}
$ g++ -std=c++23 -Wall -Wextra continuewhile.cpp -o continuewhile
$ timeout 3 ./continuewhile
Ímpares:
$ echo $?
124

O que aconteceu: i começa em 0, que é par: o continue volta para a condição sem passar pelo i++. i continua 0 para sempre, e o programa nunca mostra nada. O timeout o encerrou depois de 3 segundos (código 124, veja o laço infinito).

Como consertar: faça o passo antes do continue (ou no começo do corpo), ou use um for, cujo passo sempre roda.

"break statement not within loop or switch"
#include <iostream>

int main() {
    int x = 5;
    if (x > 3) {
        break;
    }
}
$ g++ -std=c++23 -Wall -Wextra fora.cpp -o fora
fora.cpp: In function ‘int main()’:
fora.cpp:6:9: error: break statement not within loop or switch
    6 |         break;
      |         ^~~~~

O que significa: "instrução break fora de um laço ou switch". O break não sai de um if; ele só existe dentro de while, do-while, for ou switch. O continue é ainda mais restrito: só dentro de laços. No editor do guia, o Clang diz error: 'break' statement not in loop or switch statement.

Como consertar: se a ideia era "não fazer o resto", use if/else. Se era "terminar o programa", use return 0; dentro do main.

O menu diz "Saindo..." e não sai

O que aconteceu: o break estava dentro de um switch e saiu só dele (seção 4).

Como consertar: variável de controle (bool sair), do-while (opcao != 0) ou if/else if no lugar do switch.

A busca achou mais de um resultado

O que aconteceu: com laços aninhados, o break saiu só do laço de dentro, e o de fora continuou procurando (seção 5).

Como consertar: uma variável bool achou na condição do laço de fora, ou a busca numa função com return.


Referência

FormaO que faz
break;Sai do laço (ou switch) mais próximo; segue na linha depois dele.
continue;Pula o resto desta volta; no for, roda o passo e testa a condição.
while (true) { …; if (fim) break; … }Laço com a saída no meio.
for (;;) { … }O mesmo laço "sem fim", escrito com for.
bool achou = false; for (…; … && !achou; …)Variável de controle para sair de laços aninhados.
return;Sai da função inteira, com todos os laços dela.

Exercícios

1. Parar a busca

Complete para sair do laço quando achar o número 42:

for (int n : numeros) { if (n == 42) { } }

2. Pular os negativos

Complete para somar só os números positivos:

for (int n : numeros) { if (n < 0) { } soma += n; }

3. O que aparece?

O que este laço mostra? for (int i = 1; i <= 5; i++) { if (i == 3) break; std::cout << i; }

4. E agora?

E este? for (int i = 1; i <= 5; i++) { if (i == 3) continue; std::cout << i; }

5. Um break dentro de um case de um switch, que está dentro de um while, sai de quê?

6. Qual é a forma recomendada para sair de dois laços aninhados ao mesmo tempo?

Missão final: somar só os preços válidos

Missão: a planilha da lojinha tem preços inválidos (zero ou negativos) misturados aos bons. Use continue para pular os preços menores ou iguais a zero e some o resto. O resultado deve ser Soma: 47.5.

#include <iostream>
#include <vector>

int main() {
    std::vector<double> precos = {12.5, -1.0, 8.0, 0.0, 27.0};
    double soma = 0.0;
    for (double p : precos) {
        soma += p;
    }
    std::cout << "Soma: " << soma << '\n';
}
#include <iostream>
#include <vector>

int main() {
    std::vector<double> precos = {12.5, -1.0, 8.0, 0.0, 27.0};
    double soma = 0.0;
    for (double p : precos) {
        if (p <= 0) {
            continue;
        }
        soma += p;
    }
    std::cout << "Soma: " << soma << '\n';
}

Resumo

  • break sai do laço na hora; o programa continua depois dele. Ideal para buscas: achou, parou.
  • while (true) + break põe a saída exatamente onde a decisão é tomada.
  • continue pula o resto da volta atual e vai para a próxima. No for, o passo ainda roda; no while, cuidado para não pular o passo.
  • Dentro de um switch, o break sai só do switch, não do laço.
  • Com laços aninhados, o break sai só do de dentro. Para sair dos dois: variável de controle ou função com return. O goto existe, mas evite.
  • break fora de laço ou switch não compila: break statement not within loop or switch.