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.
- Como usar
breakpara parar uma busca assim que achar o item. - Como escrever um laço "infinito de propósito" com
while (true)e sair dele combreak. - Como usar
continuepara pular itens. - A armadilha do
breakdentro de umswitch(ele não sai do laço). - Como sair de dois laços, um dentro do outro, de uma vez.
- Os erros reais:
breakfora de laço econtinueque trava owhile.
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.
break | continue | |
|---|---|---|
| O que interrompe | O laço inteiro | Só a volta atual |
| Para onde vai | Para a primeira linha depois do laço | Para 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 comstd::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
}dofor.
$ 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::coutde 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:
- Uma variável de controle (flag, "bandeirinha"), que o
case 0liga 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!
- Um
do-whilecom a condiçãoopcao != 0, como o menu da aula do-while. - Trocar o
switchporif/else if: aí obreakdentro doifsai do laço, porqueifnão "captura" obreak.
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.
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ção | Ferramenta |
|---|---|
| Achei o que procurava; o resto não interessa | break |
| Repetir até uma condição que só se sabe no meio do corpo | while (true) + break |
| Este item não interessa, mas os próximos sim | continue (ou um if em volta do resto) |
Sair do laço de dentro de um switch | Variável de controle, do-while ou if/else if |
| Sair de dois laços aninhados | Variá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
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.
#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 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.
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
| Forma | O 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:
2. Pular os negativos
Complete para somar só os números positivos:
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
breaksai do laço na hora; o programa continua depois dele. Ideal para buscas: achou, parou.while (true)+breakpõe a saída exatamente onde a decisão é tomada.continuepula o resto da volta atual e vai para a próxima. Nofor, o passo ainda roda; nowhile, cuidado para não pular o passo.- Dentro de um
switch, obreaksai só doswitch, não do laço. - Com laços aninhados, o
breaksai só do de dentro. Para sair dos dois: variável de controle ou função comreturn. Ogotoexiste, mas evite. breakfora de laço ouswitchnão compila:break statement not within loop or switch.