C break e continue

Até aqui, um laço só terminava quando a condição ficava falsa, e cada volta rodava o corpo inteiro, do começo ao fim. Às vezes você quer mais controle: parar no meio, porque já achou o que procurava, ou pular o resto de uma volta, porque aquele item não interessa. Para isso existem duas palavras: break ("quebrar", sair do laço) e continue ("continuar", ir direto para a próxima volta).

Você vai aprender
  • Como usar break para procurar e parar assim que achar.
  • O laço infinito de propósito, while (1), com a saída no meio.
  • Como saber, depois do laço, por que ele parou (com uma variável "bandeira").
  • Como usar continue para pular uma volta (os números pares, um valor inválido).
  • Por que o break sai de um laço só, mesmo quando há um laço dentro de outro.
  • Os erros reais: break fora de laço e o continue que trava o while.

Todos os programas foram compilados com o gcc 15 na máquina fictícia da Ana, na pasta ~/c, com o comando padrão do guia: gcc -std=c23 -Wall -Wextra arquivo.c -o programa.


A ideia: procurar as chaves e separar a roupa

Duas situações do dia a dia:

  • Procurando as chaves nas gavetas, uma por uma. Achou na terceira? Você para de procurar: não abre a quarta, a quinta… Isso é o break: sai do laço na hora.
  • Separando a roupa para lavar, peça por peça. Uma peça é de lã e não vai na máquina? Você a pula e passa para a próxima, mas continua separando as outras. Isso é o continue: abandona só a volta atual.
PalavraO que fazPara onde o programa vai
breakTermina o laço inteiroPara a primeira linha depois da } do laço
continueTermina só a volta atualPara o teste da condição (no for, primeiro roda o passo)

1. break: procurar e parar

A Ana quer o primeiro número, a partir de 50, que seja divisível por 7. Ela não sabe qual é, mas sabe que, ao achar, não precisa testar mais nada:

#include <stdio.h>

int main(void) {
    for (int n = 50; n <= 100; n++) {
        printf("Testando %d\n", n);
        if (n % 7 == 0) {
            printf("Achei: %d\n", n);
            break;
        }
    }
    printf("Fim da busca.\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra procurar.c -o procurar
$ ./procurar
Testando 50
Testando 51
Testando 52
Testando 53
Testando 54
Testando 55
Testando 56
Achei: 56
Fim da busca.
for (int n = 50; n <= 100; n++)
O laço poderia ir até 100 (51 voltas).
n % 7 == 0
"O resto da divisão por 7 é zero", ou seja, n é divisível por 7 (o % está em Operadores Aritméticos).
break;
Sai do for na hora. O passo n++ não roda, a condição não é testada de novo e o programa pula para Fim da busca..

Foram só 7 voltas em vez de 51. Repare que o break está dentro de um if, mas sai do laço: o break não liga para o if, ele procura o laço (ou switch) mais próximo em volta dele.

Missão: mude a busca para achar o primeiro número a partir de 100 que seja divisível por 13 (e aumente o fim do laço para 200). A saída deve terminar com Achei: 104.

#include <stdio.h>

int main(void) {
    for (int n = 50; n <= 100; n++) {
        printf("Testando %d\n", n);
        if (n % 7 == 0) {
            printf("Achei: %d\n", n);
            break;
        }
    }
    printf("Fim da busca.\n");
    return 0;
}
#include <stdio.h>

int main(void) {
    for (int n = 100; n <= 200; n++) {
        printf("Testando %d\n", n);
        if (n % 13 == 0) {
            printf("Achei: %d\n", n);
            break;
        }
    }
    printf("Fim da busca.\n");
    return 0;
}

2. while (1) com break: a saída no meio

Na aula do while, o programa que soma até o 0 precisava ler o número antes do laço e de novo no fim do corpo. Com um laço infinito de propósito e um break, a leitura aparece uma vez só, no lugar natural: no começo de cada volta.

#include <stdio.h>

int main(void) {
    int numero = 0;
    int soma = 0;
    while (1) {
        printf("Digite um número (0 para parar): ");
        if (scanf("%d", &numero) != 1 || numero == 0) {
            break;
        }
        soma += numero;
    }
    printf("Soma: %d\n", soma);
    return 0;
}
$ gcc -std=c23 -Wall -Wextra soma_break.c -o soma_break
$ ./soma_break
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
while (1)
Em C, qualquer número diferente de 0 é verdadeiro: a condição nunca fica falsa. No C23 também dá para escrever while (true) C23, e outra forma clássica é for (;;).
scanf(…) != 1 || numero == 0
"A leitura falhou ou o número é 0". Qualquer um dos dois encerra a soma.
break;
A única saída do laço. Todo while (1) precisa de pelo menos um break alcançável, senão é um laço infinito de verdade.
Quando vale a pena

while (1) com break é ótimo quando a decisão de parar fica no meio da volta (depois de ler, antes de processar). Quando dá para escrever a condição no topo de forma clara, prefira o while (condição) comum: quem lê entende o laço sem procurar o break.


3. Por que o laço parou? A variável bandeira

Um laço com break pode terminar de dois jeitos: pelo break ou porque a condição ficou falsa. Muitas vezes você precisa saber qual foi. No caixa eletrônico, a Ana tem 3 tentativas para acertar a senha:

#include <stdio.h>

int main(void) {
    int senha = 0;
    int acertou = 0;
    for (int tentativa = 1; tentativa <= 3; tentativa++) {
        printf("Senha (tentativa %d de 3): ", tentativa);
        if (scanf("%d", &senha) != 1) {
            break;
        }
        if (senha == 1234) {
            acertou = 1;
            break;
        }
        printf("Senha errada.\n");
    }
    if (acertou) {
        printf("Acesso liberado!\n");
    } else {
        printf("Cartão bloqueado.\n");
    }
    return 0;
}
$ gcc -std=c23 -Wall -Wextra senha.c -o senha
$ ./senha
Senha (tentativa 1 de 3): 1111
Senha errada.
Senha (tentativa 2 de 3): 1234
Acesso liberado!
$ ./senha
Senha (tentativa 1 de 3): 1
Senha errada.
Senha (tentativa 2 de 3): 2
Senha errada.
Senha (tentativa 3 de 3): 3
Senha errada.
Cartão bloqueado.
int acertou = 0;
Uma bandeira (em inglês, flag): uma variável que começa "abaixada" (0) e é "levantada" (1) quando algo acontece. Com C23 você pode usar bool acertou = false; (veja Booleanos).
acertou = 1; break;
Levanta a bandeira antes de sair. Depois do laço, ela conta a história.
printf("Senha errada.\n");
Só roda quando a senha não bateu: se bateu, o break saiu antes de chegar aqui.
if (acertou)
Depois do laço, a bandeira diz se saímos pelo break (acertou) ou porque as 3 tentativas acabaram.

4. continue: pular uma volta

O continue abandona o resto do corpo só nesta volta e vai para a próxima. Para mostrar só os ímpares de 1 a 10, pule os pares:

#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            continue;
        }
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra impares.c -o impares
$ ./impares
1 3 5 7 9 
if (i % 2 == 0)
"i é par" (resto da divisão por 2 é zero).
continue;
Pula o printf desta volta. Num for, o programa vai para o passo (i++) e depois testa a condição, como numa volta normal.

Claro, aqui daria para usar i += 2 começando do 1. O continue brilha quando o "pular" depende de algo que só se sabe durante a volta, como o valor que a pessoa digitou. A Ana lança as 5 vendas do dia; um valor negativo foi erro de digitação e deve ser ignorado:

#include <stdio.h>

int main(void) {
    int valor = 0;
    int soma = 0;
    for (int i = 1; i <= 5; i++) {
        printf("Venda %d: ", i);
        if (scanf("%d", &valor) != 1) {
            break;
        }
        if (valor < 0) {
            printf("  (valor negativo ignorado)\n");
            continue;
        }
        soma += valor;
    }
    printf("Total das vendas: %d\n", soma);
    return 0;
}
$ gcc -std=c23 -Wall -Wextra positivos.c -o positivos
$ ./positivos
Venda 1: 30
Venda 2: -5
  (valor negativo ignorado)
Venda 3: 20
Venda 4: 15
Venda 5: -1
  (valor negativo ignorado)
Total das vendas: 65

Os dois negativos não entraram na soma (30 + 20 + 15 = 65), mas o laço continuou até a venda 5. O mesmo programa usa os dois: break quando a leitura falha (não adianta continuar) e continue quando só aquele valor é ruim.

Missão: mude o programa para mostrar os números de 1 a 20, pulando os múltiplos de 3 (3, 6, 9…) com continue. A saída deve ser 1 2 4 5 7 8 10 11 13 14 16 17 19 20.

#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            continue;
        }
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}
#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 20; i++) {
        if (i % 3 == 0) {
            continue;
        }
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

5. O break só sai de um laço

Quando há um laço dentro de outro (assunto da próxima aula, Laços Aninhados), o break sai só do laço mais de dentro, aquele que o envolve diretamente. O de fora continua:

#include <stdio.h>

int main(void) {
    for (int linha = 1; linha <= 3; linha++) {
        for (int coluna = 1; coluna <= 5; coluna++) {
            if (coluna == 3) {
                break;
            }
            printf("(%d,%d) ", linha, coluna);
        }
        printf("<- fim da linha %d\n", linha);
    }
    return 0;
}
$ gcc -std=c23 -Wall -Wextra umlaco.c -o umlaco
$ ./umlaco
(1,1) (1,2) <- fim da linha 1
(2,1) (2,2) <- fim da linha 2
(3,1) (3,2) <- fim da linha 3

Em cada linha, o break interrompeu as colunas na 3, mas o laço das linhas seguiu: as três linhas apareceram. Para sair dos dois laços de uma vez, use uma bandeira ou, em casos especiais, um goto; os dois jeitos estão em Laços Aninhados. O continue segue a mesma regra: ele pula a volta do laço mais de dentro.

break dentro de switch

O break também sai de um switch. Por isso, num menu com switch dentro de um laço (como o da aula do while), o break de cada case sai só do switch: o laço continua e o menu aparece de novo. Já o continue não tem nada a ver com switch: dentro dele, vale para o laço em volta.


Formas diferentes de escrever

O mesmo laço com e sem break

A busca do começo da aula poderia colocar o "achei" na própria condição, usando uma bandeira:

int achou = 0;
for (int n = 50; n <= 100 && !achou; n++) {
    if (n % 7 == 0) {
        printf("Achei: %d\n", n);
        achou = 1;
    }
}

Funciona, mas a condição ficou mais difícil de ler. Com break, a regra de parada fica bem onde a coisa acontece. Os dois estilos são corretos; use o que deixar o código mais claro.

continue ou if ao contrário?

Todo continue pode virar um if com a condição invertida:

for (int i = 1; i <= 10; i++) {
    if (i % 2 != 0) {
        printf("%d ", i);
    }
}

Com um teste só, o if invertido é mais simples. O continue ganha quando há vários motivos para pular no começo da volta ("se for negativo, pula; se for maior que 1000, pula…"): cada um vira uma linha, e o código "bom" não fica enterrado dentro de vários if.


Quando dá errado

"break statement not within loop or switch"
#include <stdio.h>

int main(void) {
    int idade = 15;
    if (idade < 18) {
        printf("Menor de idade.\n");
        break;
    }
    printf("Fim\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra foraloop.c -o foraloop
foraloop.c: In function ‘main’:
foraloop.c:7:9: error: break statement not within loop or switch
    7 |         break;
      |         ^~~~~

O que significa: "instrução break fora de um laço ou switch". O break não serve para sair de um if. O Clang do editor diz error: 'break' statement not in loop or switch statement.

Como consertar: se a ideia era parar o resto do if, use else (veja if e else). Se era encerrar o programa, use return 0; (dentro do main).

"continue statement not within a loop"
$ gcc -std=c23 -Wall -Wextra foraloop2.c -o foraloop2
foraloop2.c: In function ‘main’:
foraloop2.c:6:9: error: continue statement not within a loop
    6 |         continue;
      |         ^~~~~~~~

O que significa: "instrução continue fora de um laço". Mesmo caso: o continue estava num if sem laço em volta. Repare que a mensagem não cita o switch: o continue só existe para laços. No Clang: error: 'continue' statement not in loop statement.

O continue trava o while
#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 10) {
        if (i % 2 == 0) {
            continue;
        }
        printf("%d\n", i);
        i++;
    }
    printf("Fim\n");
    return 0;
}
$ gcc -std=c23 -Wall -Wextra continue_while.c -o continue_while
$ timeout 3 ./continue_while
1
$ echo $?
124

O que aconteceu: mostrou 1, somou 1 (i vira 2) e travou. Com i valendo 2, o continue pula o resto do corpo, inclusive o i++. No while não existe "passo" separado: o i fica em 2 para sempre. Num for isso não acontece, porque o continue do for sempre roda o passo.

Como consertar: troque por um for (int i = 1; i <= 10; i++), ou faça o i++ antes do continue (por exemplo, logo no começo do corpo, ajustando o resto).

Esperava sair dos dois laços, mas só saiu de um

O que aconteceu: o break estava no laço de dentro e o de fora continuou rodando, como no exemplo umlaco.c. O compilador não avisa: é o comportamento normal do C.

Como consertar: use uma bandeira testada no laço de fora (ou um goto), como em Laços Aninhados.


Referência

FormaO que faz
break;Sai do laço (for, while, do while) ou switch mais próximo. Vai para a linha depois da }.
continue;Pula o resto da volta. No for, roda o passo e testa; no while/do while, vai direto ao teste.
while (1) { … if (…) break; … }Laço com a saída no meio. Também: for (;;) e, no C23, while (true).
int achou = 0; … achou = 1; break;Bandeira: diz depois do laço se ele parou pelo break.
if (ruim) continue;Ignorar um item e seguir com os outros.

Exercícios

1. Sair do laço

Complete para o laço parar quando i chegar a 5:

for (int i = 1; i <= 10; i++) { if (i == 5) { } printf("%d\n", i); }

2. Quantos números aparecem?

No laço do exercício 1, quantos números são mostrados?

3. Pular uma volta

Complete para não mostrar o número 3:

for (int i = 1; i <= 5; i++) { if (i == 3) { } printf("%d\n", i); }

4. Há um for dentro de outro for, e um break no de dentro. O que acontece quando ele roda?

5. Por que while (i <= 10) { if (i % 2 == 0) continue; printf(…); i++; } trava?

6. O gcc deu error: break statement not within loop or switch. O que isso quer dizer?

Missão final: a senha com 3 tentativas

Missão: este programa lê as 3 tentativas, mas nunca libera o acesso. Quando a senha for 1234, mostre Acesso liberado na tentativa N! (com o número da tentativa) e saia do laço com break. A entrada já traz 1111, 4321 e 1234.

#include <stdio.h>

int main(void) {
    int senha = 0;
    for (int tentativa = 1; tentativa <= 3; tentativa++) {
        printf("Senha (tentativa %d de 3): ", tentativa);
        if (scanf("%d", &senha) != 1) {
            break;
        }
        printf("Senha errada.\n");
    }
    return 0;
}
#include <stdio.h>

int main(void) {
    int senha = 0;
    for (int tentativa = 1; tentativa <= 3; tentativa++) {
        printf("Senha (tentativa %d de 3): ", tentativa);
        if (scanf("%d", &senha) != 1) {
            break;
        }
        if (senha == 1234) {
            printf("Acesso liberado na tentativa %d!\n", tentativa);
            break;
        }
        printf("Senha errada.\n");
    }
    return 0;
}

Resumo

  • break sai do laço (ou switch) na hora; o programa segue depois da }.
  • continue pula o resto da volta atual; no for, o passo ainda roda.
  • while (1) (ou for (;;), ou while (true) no C23) com break serve quando a decisão de parar fica no meio da volta.
  • Uma bandeira (int achou = 0;) conta, depois do laço, se ele parou pelo break.
  • Os dois agem só sobre o laço mais de dentro.
  • continue num while pode pular o passo e travar o laço; break/continue fora de laço é erro de compilação.