Como faço para interromper loops aninhados em Java?


1819

Eu tenho uma construção de loop aninhado como este:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             break; // Breaks out of the inner loop
         }
    }
}

Agora, como posso sair dos dois loops? Eu olhei para perguntas semelhantes, mas nenhuma diz respeito especificamente ao Java. Não pude aplicar essas soluções porque a maioria usava gotos.

Não quero colocar o loop interno em um método diferente.

Não quero executar novamente os loops. Ao quebrar, terminei com a execução do bloco de loop.

Respostas:


2427

Como outros respondedores, eu definitivamente preferiria colocar os loops em um método diferente; nesse momento, você pode simplesmente voltar para parar de iterar completamente. Esta resposta mostra apenas como os requisitos da pergunta podem ser atendidos.

Você pode usar breakcom um rótulo para o loop externo. Por exemplo:

public class Test {
    public static void main(String[] args) {
        outerloop:
        for (int i=0; i < 5; i++) {
            for (int j=0; j < 5; j++) {
                if (i * j > 6) {
                    System.out.println("Breaking");
                    break outerloop;
                }
                System.out.println(i + " " + j);
            }
        }
        System.out.println("Done");
    }
}

Isso imprime:

0 0
0 1
0 2
0 3
0 4
1 0
1 1
1 2
1 3
1 4
2 0
2 1
2 2
2 3
Breaking
Done

286
Isso faz saltar para logo após o loop. Tente! Sim, o rótulo vem antes do loop, mas é porque está rotulando o loop, e não no lugar para o qual você deseja sair. (Você pode continuar com um rótulo também.)
Jon Skeet

2
O Perl também permite esse sistema de etiquetas próprio. Eu acho que muitas linguagens - dificilmente me surpreende que esteja em Java.
Evan Carroll

9
@Evan - essa afirmação é claramente verdadeira - em idiomas que prometem ser verdade. Mas Java não faz essa promessa. Se um idioma está em conflito com suas suposições, é possível que sejam suas suposições que estão com defeito. Nesse caso, acho que você ainda está parcialmente certo - princípio de menos surpresa WRT para muitos que nunca ouviram falar (ou esqueceram) dessa forma break. Mesmo assim, as exceções são outra exceção mais conhecida (desculpe). Mas eu ainda ficaria descontente com isso se não fosse óbvio (pequenos loops, comentário de aviso se o rótulo / quebra ainda não estiver visível o suficiente).
precisa saber é o seguinte

6
@MuhammadBabar: outerloopé um rótulo. Não sei exatamente qual código você tentou, mas o código na minha resposta compila e roda muito bem.
Jon Skeet

4
@NisargPatil Só porque está no sonar, oint não faz dele um cheiro de código. Significa apenas que houve um desenvolvedor que adicionou isso ao sonarLint com um desejo pessoal de arranhar, e está cheio desses tipos de regras que só fazem sentido quando abusadas ou porque algum desenvolvedor tem uma cruzada de ódio pessoal contra eles. As quebras e continuações rotuladas são uma maneira muito elegante de descrever o que você deseja fazer.
john16384

403

Tecnicamente, a resposta correta é rotular o loop externo. Na prática, se você quiser sair a qualquer momento dentro de um loop interno, seria melhor externalizar o código em um método (um método estático, se necessário) e depois chamá-lo.

Isso compensaria pela legibilidade.

O código se tornaria algo assim:

private static String search(...) 
{
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                return search;
            }
        }
    }
    return null; 
}

Correspondendo ao exemplo da resposta aceita:

 public class Test {
    public static void main(String[] args) {
        loop();
        System.out.println("Done");
    }

    public static void loop() {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                if (i * j > 6) {
                    System.out.println("Breaking");
                    return;
                }
                System.out.println(i + " " + j);
            }
        }
    }
}

30
Às vezes, você usa várias variáveis ​​locais que estão fora do loop interno, passar todas elas pode parecer desajeitado.
Haoest 07/12/11

1
Então, como essa solução deve imprimir "Concluído", como na resposta aceita?
7898 JohnDoe

1
@ JohnDoe você chama e depois imprime System.out.println ("done"); tente {} finalmente {} no método de pesquisa também é uma opção.
Zo72

2
Acho que é uma prática melhor, mas o que acontece se você quiser continuar em vez de quebrar? Os rótulos suportam igualmente bem (ou muito mal!), Mas não sei como converter essa lógica para continuar.
Rob Grant

@RobertGrant Se você quiser continuar em vez de interromper, mova o loop externo para fora do loopmétodo e retorne do método para continuar.
Muhd

215

Você pode usar um bloco nomeado ao redor dos loops:

search: {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition) {
                // Do something and break...
                break search;
            }
        }
    }
}

40
Você não precisa criar um novo bloco para usar um rótulo.
911 Jon Skeet

81
Não, mas torna a intenção muito mais clara. Veja o primeiro comentário sobre a resposta aceita.
Bombe

2
Na verdade, não é um bloco nomeado. Após o rótulo, você pode escrever qualquer expressão Java como sem rótulo, name: if(...){...}faz condição nomeada? :)
La VloZ Merrill

4
Essa construção tem uma grande vantagem sobre a rotulação fordireta. Você pode adicionar um código antes do último }que será executado apenas se a condição nunca for atendida.
Florian F

2
É um bloco nomeado e não um loop nomeado. Você não pode, dentro desse loop, "continuar a pesquisa"; que é totalmente uma sintaxe legal se o loop for nomeado como pesquisa. Você pode quebrá-lo, mas não pode continuar.
Tatarize

132

Eu nunca uso etiquetas. Parece uma prática ruim entrar. Aqui está o que eu faria:

boolean finished = false;
for (int i = 0; i < 5 && !finished; i++) {
    for (int j = 0; j < 5; j++) {
        if (i * j > 6) {
            finished = true;
            break;
        }
    }
}

4
Isso não deveria ser em && !finishedvez de || !finished? E por que usar breake não usar também && !finishedpara o loop interno?
Gandalf

4
Eu uso breakpara poder sair arbitrariamente do loop. Se houver código após esse ifbloco, você pode breakantes que ele seja executado. Mas você está certo &&. Corrigido.
Elle Mundy 29/07

2
boa solução! é exatamente assim que eu faria na prática se não fosse preferível colocá-lo em uma função extra por algum motivo.
benroth

6
Há um problema potencial se há alguma lógica após o loop interno ... que vai continuar a receber executado e as quebras de loop externo somente quando a nova iteração começa ...
Karthik Karuppannan

7
Eu não entendo por que alguém deveria fazer assim. As pessoas que trabalham com código devem poder usar todos os recursos de um idioma. Entendo que é importante escrever código que outras pessoas possam entender, mas não restringindo o uso de ferramentas oficiais fornecidas por um idioma e encontrar soluções alternativas para a mesma funcionalidade. Ou você quis dizer outra coisa com "má prática"?
codepleb

107

Você pode usar etiquetas:

label1: 
for (int i = 0;;) {
    for (int g = 0;;) {
      break label1;
    }
}

4
Tenha um +1 de mim. Simples, direto ao ponto, responde à pergunta. Não pode ser acusado de repetir uma resposta existente porque você respondeu ao mesmo tempo.
precisa

40

Use uma função:

public void doSomething(List<Type> types, List<Type> types2){
  for(Type t1 : types){
    for (Type t : types2) {
      if (some condition) {
         // Do something and return...
         return;
      }
    }
  }
}

20

Você pode usar uma variável temporária:

boolean outerBreak = false;
for (Type type : types) {
   if(outerBreak) break;
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             outerBreak = true;
             break; // Breaks out of the inner loop
         }
    }
}

Dependendo da sua função, você também pode sair / retornar do loop interno:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
             // Do something and break...
             return;
         }
    }
}

7
Acho esse caminho meio confuso.
20209

11
Uma verificação extra de condição toda vez que você passa pelo loop? Não, obrigado.
perfil completo de ryandenki

15

Se você não gosta de breaks e gotos, pode usar um loop for "tradicional" em vez do for-in, com uma condição de abortamento extra:

int a, b;
bool abort = false;
for (a = 0; a < 10 && !abort; a++) {
    for (b = 0; b < 10 && !abort; b++) {
        if (condition) {
            doSomeThing();
            abort = true;
        }
    }
}

2
Não é adequado para forçar loops.
John McClane

1
@JohnMcClane E você está enviando spam para muitas respostas em uma pergunta de 9 anos ou mais porque ...?
Quintec 7/12

12

Eu precisava fazer uma coisa semelhante, mas optei por não usar o loop for aprimorado para fazer isso.

int s = type.size();
for (int i = 0; i < s; i++) {
    for (int j = 0; j < t.size(); j++) {
        if (condition) {
            // do stuff after which you want 
            // to completely break out of both loops
            s = 0; // enables the _main_ loop to terminate
            break;
        }
    }
}

Não acho legal iterar todos os itens após a condição ser quebrada. Assim, eu acrescentaria uma quebra no caso else.
boutta

Não estou certo de como você está chegando a essa conclusão. Quando a condição é verdadeira, os dois loops são encerrados.
Swifty McSwifterton

OK, eu não entendi a parte com a manipulação do 's' var. Mas acho esse tipo de estilo ruim, já que s representa o tamanho. Então eu prefiro a resposta de ddyer com vars explícitas: stackoverflow.com/a/25124317/15108
boutta

Você pode mudar spara um valor menor iou mudar ipara um valor maior ou igual a s, ambos devem fazer o truque. Você está certo em mudar s, porque pode ser usado em outro lugar mais tarde, mas a mudança inão prejudicará, apenas garantirá que a primeira fornão continue em loop.
Zsolti 27/09/17

9

Eu prefiro adicionar uma "saída" explícita aos testes de loop. Isso deixa claro para qualquer leitor casual que o loop pode terminar mais cedo.

boolean earlyExit = false;
for(int i = 0 ; i < 10 && !earlyExit; i++) {
     for(int j = 0 ; i < 10 && !earlyExit; j++) { earlyExit = true; }
}

Não é adequado para forçar loops.
John McClane

8

StreamSolução Java 8 :

List<Type> types1 = ...
List<Type> types2 = ...

types1.stream()
      .flatMap(type1 -> types2.stream().map(type2 -> new Type[]{type1, type2}))
      .filter(types -> /**some condition**/)
      .findFirst()
      .ifPresent(types -> /**do something**/);

1
@ Tvde1 e ainda útil para outros usuários, por isso novos métodos e soluções são sempre bem-vindos
Andrei Suvorkov

Uau, isso é feio.
DS.

7

Normalmente, nesses casos, ele está no escopo de uma lógica mais significativa, digamos, alguma pesquisa ou manipulação sobre alguns dos objetos iterados 'for' em questão, então geralmente uso a abordagem funcional:

public Object searching(Object[] types) { // Or manipulating
    List<Object> typesReferences = new ArrayList<Object>();
    List<Object> typesReferences2 = new ArrayList<Object>();

    for (Object type : typesReferences) {
        Object o = getByCriterion(typesReferences2, type);
        if(o != null) return o;
    }
    return null;
}

private Object getByCriterion(List<Object> typesReferences2, Object criterion) {
    for (Object typeReference : typesReferences2) {
        if(typeReference.equals(criterion)) {
             // here comes other complex or specific logic || typeReference.equals(new Object())
             return typeReference;
        }
    }
    return null;
}

Principais contras:

  • aproximadamente duas vezes mais linhas
  • maior consumo de ciclos de computação, o que significa que é mais lento do ponto de vista algorítmico
  • mais trabalho de digitação

Os prós:

  • a maior proporção de separação de preocupações devido à granularidade funcional
  • maior proporção de reutilização e controle da lógica de pesquisa / manipulação sem
  • os métodos não são longos, portanto são mais compactos e fáceis de compreender
  • maior proporção de legibilidade

Portanto, é apenas lidar com o caso através de uma abordagem diferente.

Basicamente, uma pergunta ao autor desta pergunta: o que você considera dessa abordagem?


6

Você pode interromper todos os loops sem usar nenhum rótulo: e sinalizadores.

É apenas uma solução complicada.

Aqui a condição1 é a condição usada para interromper o loop K e J. E a condição2 é a condição usada para interromper o loop K, J e I.

Por exemplo:

public class BreakTesting {
    public static void main(String[] args) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                for (int k = 0; k < 9; k++) {
                    if (condition1) {
                        System.out.println("Breaking from Loop K and J");
                        k = 9;
                        j = 9;
                    }
                    if (condition2) {
                        System.out.println("Breaking from Loop K, J and I");
                        k = 9;
                        j = 9;
                        i = 9;
                    }
                }
            }
        }
        System.out.println("End of I , J , K");
    }
}

2
Como eu usaria isso com loops for-each? ;)
Willi Mentzel

5
Isso não funciona se você tiver uma condição de loop mais sofisticada, como list.size ()> 5. Também é realmente apenas um hack. É difícil ler e praticar mal!
Neuron

É propenso a erros. Imagine que você mudou o circuito interno para (int k = 0; k < 10; k++)e você não corrigir todas as k = 9para k = 10. Você pode entrar em um loop infinito.
Florian F

5

O conceito de interrupção rotulada é usado para interromper loops aninhados em java, usando break rotulado você pode interromper o aninhamento de loops em qualquer posição. Exemplo 1:

loop1:
 for(int i= 0; i<6; i++){
    for(int j=0; j<5; j++){
          if(i==3)
            break loop1;
        }
    }

suponha que existam 3 loops e você queira finalizar o loop3: Exemplo 2:

loop3: 
for(int i= 0; i<6; i++){
loop2:
  for(int k= 0; k<6; k++){
loop1:
    for(int j=0; j<5; j++){
          if(i==3)
            break loop3;
        }
    }
}

4
boolean broken = false; // declared outside of the loop for efficiency
for (Type type : types) {
    for (Type t : types2) {
        if (some condition) {
            broken = true;
            break;
        }
    }

    if (broken) {
        break;
    }
}

4

Se estiver dentro de alguma função, por que você não a devolve:

for (Type type : types) {
    for (Type t : types2) {
         if (some condition) {
            return value;
         }
    }
}

Eu prefiro esse padrão. Isso muitas vezes me fez quebrar os loops em uma função separada. Meu código sempre foi melhor depois de fazer isso, portanto, por esse motivo, eu realmente gosto dessa resposta.
Bill K

4

Melhor e fácil método ..

outerloop:
for(int i=0; i<10; i++){
    // here we can break Outer loop by 
    break outerloop;

    innerloop:
    for(int i=0; i<10; i++){
        // here we can break innerloop by 
        break innerloop;
     }
}

4
Esses exemplos de quebra não são muito úteis, porque mesmo sem o rótulo, eles quebrariam no mesmo ponto. Também é sempre bom ter código que você pode realmente executar, o que não é o caso com o seu código, uma vez que o innerloop nunca pode ser alcançado ..
Neuron

Eu ia digitar a mesma coisa. Os rótulos são um pouco inúteis neste caso.
Taslim Oseni

4

Abordagem bastante incomum, mas em termos de tamanho do código ( não desempenho ), essa é a coisa mais fácil que você pode fazer:

for(int i = 0; i++; i < j) {
    if(wanna exit) {
        i = i + j; // if more nested, also add the 
                   // maximum value for the other loops
    }
}


4

Outra solução, mencionada sem exemplo (na verdade, funciona no código prod).

try {
    for (Type type : types) {
        for (Type t : types2) {
            if (some condition #1) {
                // Do something and break the loop.
                throw new BreakLoopException();
            }
        }
    }
}
catch (BreakLoopException e) {
    // Do something on look breaking.
}

Obviamente, BreakLoopExceptiondeve ser interno, privado e acelerado com rastreamento sem pilha:

private static class BreakLoopException extends Exception {
    @Override
    public StackTraceElement[] getStackTrace() {
        return new StackTraceElement[0];
    }
}

1
Ele foi mencionado na verdade, em uma resposta recebendo -23 votos ... stackoverflow.com/a/886980/2516301 . Ele vai fazer o trabalho, mas é uma prática de programação muito ruim ...
vefthym

de fato. no entanto, vi esse código legado - loops aninhados de 4 níveis com várias condições de interrupção. e era mais legível com exceções do que com código embutido. -23 votos é principalmente classificação emocional, mas sim - essa abordagem deve ser usada com cuidado.
ursa

1
Seria ainda mais legível se tivesse sido interrompido em uma chamada de função separada com retorno central. Frequentemente aperfeiçoada por um pouco de refator, faz sentido como uma função autônoma (geralmente reutilizável).
Bill K

2

for (int j = 0; j < 5; j++) //inner loop deve ser substituído por for (int j = 0; j < 5 && !exitloops; j++) .

Aqui, nesse caso, loops aninhados completos devem sair se a condição for True. Mas se usarmos exitloopsapenas para o superiorloop

 for (int i = 0; i < 5 && !exitloops; i++) //upper loop

O loop interno continuará, porque não há sinalizador extra que notifique esse loop interno para sair.

Exemplo: se i = 3e j=2, em seguida, é condição false. Mas, na próxima iteração do loop interno j=3 , em seguida, a condição (i*j)se tornar 9o que é true, mas loop interno será continuar até jse tornar 5.

Portanto, ele deve usar exitloopstambém os loops internos.

boolean exitloops = false;
for (int i = 0; i < 5 && !exitloops; i++) { //here should exitloops as a Conditional Statement to get out from the loops if exitloops become true. 
    for (int j = 0; j < 5 && !exitloops; j++) { //here should also use exitloops as a Conditional Statement. 
        if (i * j > 6) {
            exitloops = true;
            System.out.println("Inner loop still Continues For i * j is => "+i*j);
            break;
        }
        System.out.println(i*j);
    }
}

2

Como na sugestão de INFORMAÇÃO @ 1800, use a condição que quebra o loop interno como uma condição no loop externo:

boolean hasAccess = false;
for (int i = 0; i < x && hasAccess == false; i++){
    for (int j = 0; j < y; j++){
        if (condition == true){
            hasAccess = true;
            break;
        }
    }
}

2

Se for uma nova implementação, você pode tentar reescrever a lógica como instruções if-else_if-else.

while(keep_going) {

    if(keep_going && condition_one_holds) {
        // Code
    }
    if(keep_going && condition_two_holds) {
        // Code
    }
    if(keep_going && condition_three_holds) {
        // Code
    }
    if(keep_going && something_goes_really_bad) {
        keep_going=false;
    }
    if(keep_going && condition_four_holds) {
        // Code
    }
    if(keep_going && condition_five_holds) {
        // Code
    }
}

Caso contrário, você pode tentar definir um sinalizador quando essa condição especial ocorrer e verificar esse sinalizador em cada uma de suas condições de loop.

something_bad_has_happened = false;
while(something is true && !something_bad_has_happened){
    // Code, things happen
    while(something else && !something_bad_has_happened){
        // Lots of code, things happens
        if(something happened){
            -> Then control should be returned ->
            something_bad_has_happened=true;
            continue;
        }
    }
    if(something_bad_has_happened) { // The things below will not be executed
        continue;
    }

    // Other things may happen here as well, but they will not be executed
    //  once control is returned from the inner cycle.
}

AQUI! Portanto, embora uma simples pausa não funcione, ela pode ser feita para funcionar usando continue.

Se você está simplesmente portando a lógica de uma linguagem de programação para Java e apenas quer que a coisa funcione, tente usar rótulos .


2

Demo for break, continuee label:

Palavras-chave Java breake continuetêm um valor padrão. É o "loop mais próximo", e hoje, depois de alguns anos usando Java, acabei de conseguir!

Parece usado raro, mas útil.

import org.junit.Test;

/**
 * Created by cui on 17-5-4.
 */

public class BranchLabel {
    @Test
    public void test() {
        System.out.println("testBreak");
        testBreak();

        System.out.println("testBreakLabel");
        testBreakLabel();

        System.out.println("testContinue");
        testContinue();
        System.out.println("testContinueLabel");
        testContinueLabel();
    }

    /**
     testBreak
     a=0,b=0
     a=0,b=1
     a=1,b=0
     a=1,b=1
     a=2,b=0
     a=2,b=1
     a=3,b=0
     a=3,b=1
     a=4,b=0
     a=4,b=1
     */
    public void testBreak() {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (b == 2) {
                    break;
                }
                System.out.println("a=" + a + ",b=" + b);
            }
        }
    }

    /**
     testContinue
     a=0,b=0
     a=0,b=1
     a=0,b=3
     a=0,b=4
     a=1,b=0
     a=1,b=1
     a=1,b=3
     a=1,b=4
     a=2,b=0
     a=2,b=1
     a=2,b=3
     a=2,b=4
     a=3,b=0
     a=3,b=1
     a=3,b=3
     a=3,b=4
     a=4,b=0
     a=4,b=1
     a=4,b=3
     a=4,b=4
     */
    public void testContinue() {
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                if (b == 2) {
                    continue;
                }
                System.out.println("a=" + a + ",b=" + b);
            }
        }
    }

    /**
     testBreakLabel
     a=0,b=0,c=0
     a=0,b=0,c=1
     * */
    public void testBreakLabel() {
        anyName:
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                for (int c = 0; c < 5; c++) {
                    if (c == 2) {
                        break anyName;
                    }
                    System.out.println("a=" + a + ",b=" + b + ",c=" + c);
                }
            }
        }
    }

    /**
     testContinueLabel
     a=0,b=0,c=0
     a=0,b=0,c=1
     a=1,b=0,c=0
     a=1,b=0,c=1
     a=2,b=0,c=0
     a=2,b=0,c=1
     a=3,b=0,c=0
     a=3,b=0,c=1
     a=4,b=0,c=0
     a=4,b=0,c=1
     */
    public void testContinueLabel() {
        anyName:
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 5; b++) {
                for (int c = 0; c < 5; c++) {
                    if (c == 2) {
                        continue anyName;
                    }
                    System.out.println("a=" + a + ",b=" + b + ",c=" + c);
                }
            }
        }
    }
}

2

Demo

public static void main(String[] args) {
    outer:
    while (true) {
        while (true) {
            break outer;
        }
    }
}

1

Você pode fazer o seguinte:

  1. defina uma variável local como false

  2. defina essa variável trueno primeiro loop, quando quiser quebrar

  3. então você pode verificar no loop externo, se a condição está definida, também se romperá com o loop externo.

    boolean isBreakNeeded = false;
    for (int i = 0; i < some.length; i++) {
        for (int j = 0; j < some.lengthasWell; j++) {
            //want to set variable if (){
            isBreakNeeded = true;
            break;
        }
    
        if (isBreakNeeded) {
            break; //will make you break from the outer loop as well
        }
    }

1

Para alguns casos, podemos usar o whileloop efetivamente aqui.

Random rand = new Random();
// Just an example
for (int k = 0; k < 10; ++k) {
    int count = 0;
    while (!(rand.nextInt(200) == 100)) {
       count++;
    }

    results[k] = count;
}

1

O Java não possui um recurso goto, como no C ++. Mas ainda assim, gotoé uma palavra-chave reservada em Java. Eles podem implementá-lo no futuro. Para sua pergunta, a resposta é que existe algo chamado rótulo em Java ao qual você pode aplicar uma declaração continuee break. Encontre o código abaixo:

public static void main(String ...args) {
    outerLoop: for(int i=0;i<10;i++) {
    for(int j=10;j>0;j--) {
        System.out.println(i+" "+j);
        if(i==j) {
            System.out.println("Condition Fulfilled");
            break outerLoop;
        }
    }
    }
    System.out.println("Got out of the outer loop");
}

1

Até criar um sinalizador para o loop externo e verificar se após cada execução do loop interno pode ser a resposta.

Como isso:

for (Type type : types) {
    boolean flag=false;
    for (Type t : types2) {
        if (some condition) {
            // Do something and break...
            flag=true;
            break; // Breaks out of the inner loop
        }
    }
    if(flag)
        break;
}

1
boolean condition = false;
for (Type type : types) {
    for (int i = 0; i < otherTypes.size && !condition; i ++) {
        condition = true; // If your condition is satisfied
    }
}

Use conditioncomo um sinalizador para quando terminar o processamento. Então, o loop interno continua apenas enquanto a condição não for atendida. De qualquer forma, o loop externo continuará funcionando.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.