CodeGym /Blogue Java /Random-PT /A instrução while
John Squirrels
Nível 41
San Francisco

A instrução while

Publicado no grupo Random-PT
Nossos primeiros programas eram uma sequência de instruções executadas uma após a outra. Sem garfos. Isso inclui HelloWorld, que exibe uma saudação. Inclui cálculos aritméticos. Depois de nossos primeiros programas, aprendemos a ramificar, ou seja, como fazer um programa executar diferentes ações dependendo de condições específicas. Aqui está o código para controlar um sistema de aquecimento central e ar condicionado:

if (tempRoom>tempComfort)
    airConditionerOn();
if (tempRoom<tempComfort)
    heaterOn();
Dê o próximo passo. Na vida cotidiana, muitas vezes realizamos ações repetitivas uniformes, por exemplo, descascar maçãs para fazer uma torta. Este processo fascinante pode ser descrito como:
  1. Se houver maçãs na tigela, executamos as etapas 1.1 a 1.4:

    1. 1.1. Pegue uma maçã
    2. 1.2. Descasque e corte em fatias
    3. 1.3. Arrume as fatias de maçã na massa da torta em uma assadeira
    4. 1.4. Retorne ao passo 1.
A instrução while - 2Digamos que você tenha dez maçãs, duas mãos e uma faca. Na vida real, você descasca sequencialmente a dúzia inteira, seguindo o mesmo algoritmo para cada maçã. Mas como fazemos um programa executar uma ação repetitiva para cada maçã?
  • Nós nos amarramos ao número de maçãs, mas se não tivermos o suficiente, alguns dos comandos seriam executados sem uma "carga útil" (e poderíamos nos cortar ao tentar descascar uma maçã inexistente).
  • Se houver mais maçãs do que comandos para descascar, algumas das maçãs serão deixadas com casca.
  • Esse código é difícil de ler. Tem muitas repetições e é difícil de modificar.

Loops são instruções que permitem que ações sejam executadas repetidamente

O loop while do Java funcionará bem em nosso caso. Essa construção coloca várias ações em uma estrutura concisa e compreensível. Usando um loop while , um algoritmo de fatiamento de maçã para uma torta pode se parecer com isto em Java:

while (numberOfApplesInBowl > 0) {
    apple = bowl.grabNextApple();
    arrangeInPie(apple.peel().slice());
    numberOfApplesInBow--; // "--" is the decrement operator, which reduces the number of apples by one
}
System.out.println("The apples for the pie have been processed.");

Sintaxe do comando

A primeira variante da instrução while é assim:

while (Boolean expression) {
	// Loop body — the statement(s) that are repeatedly executed
}
Aqui está uma explicação passo a passo do que acontece quando esse código é executado:
  1. Avaliamos a expressão booleana encontrada entre parênteses após a palavra-chave while .
  2. Se a expressão booleana for avaliada como verdadeira, as instruções no corpo do loop serão executadas. Depois que a última instrução no corpo do loop for executada, vamos para a etapa 1
  3. Se a expressão booleana for avaliada como falsa, saltamos para a primeira instrução após o loop while .

Loop com uma pré-condição

Como sempre avaliamos a expressão booleana (a condição para entrar no loop) antes de executarmos o corpo do loop, essa forma do loop while costuma ser chamada de loop com uma pré-condição . Vamos construir uma tabela das primeiras dez potências de um número:

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = 1; // The result of exponentiation
    int exponent = 1; // The initial exponent
    while (exponent <= 10) { // The condition for entering the loop
        result = result * base;
        System.out.println(base + " raised to the power of " + exponent + " = " + result);
        exponent++;
    }
}
Saída do console:

3 raised to the power of 1 = 3
3 raised to the power of 2 = 9
3 raised to the power of 3 = 27
3 raised to the power of 4 = 81
3 raised to the power of 5 = 243
3 raised to the power of 6 = 729
3 raised to the power of 7 = 2187
3 raised to the power of 8 = 6561
3 raised to the power of 9 = 19683
3 raised to the power of 10 = 59049
Process finished with exit code 0

Loop com uma pós-condição

Aqui está a segunda variante deste loop:

do {
    // Loop body — the statement(s) that are repeatedly executed
} while (Boolean expression);
Aqui está uma explicação do que acontece quando este código é executado:
  1. O corpo do loop é executado (imediatamente após a palavra-chave do ).
  2. Avaliamos a expressão booleana encontrada entre parênteses após a palavra-chave while .
  3. Se a expressão booleana for avaliada como verdadeira, vamos para a etapa 1
  4. Se a expressão booleana for avaliada como falsa, saltamos para a primeira instrução após o loop while .
As duas principais diferenças em relação ao loop anterior são: 1) o corpo do loop é executado pelo menos uma vez e 2) a expressão booleana é avaliada após a execução do corpo do loop. Conseqüentemente, esse tipo de loop while é chamado de loop com uma pós-condição . Desta vez mostraremos uma tabela de potências de um número que não exceda 10000:

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = base; // The result of exponentiation
    int exponent = 1; // The initial exponent
    do {
        System.out.println(base + " raised to the power of " + exponent + " = " + result);
        exponent++;
        result = result * base;
    } while (result < 10000); // The condition for exiting the loop
}
Saída do console:

3 raised to the power of 1 = 3
3 raised to the power of 2 = 9
3 raised to the power of 3 = 27
3 raised to the power of 4 = 81
3 raised to the power of 5 = 243
3 raised to the power of 6 = 729
3 raised to the power of 7 = 2187
3 raised to the power of 8 = 6561
Process finished with exit code 0
Preste atenção às mudanças no código. Compare isso com o loop com uma pré-condição.

Fatos interessantes sobre como trabalhar com loops

Instruções de ramificação dentro do corpo do loop

Existem duas instruções que afetam a execução dentro de um loop: break (que discutiremos com mais detalhes no próximo capítulo) e continuar.
  • continue — pula a execução do restante do corpo do loop na iteração atual e pula para a avaliação da expressão booleana da instrução while. Se a expressão for avaliada como verdadeira, o loop continua.
  • break — encerra imediatamente a execução da iteração atual e transfere o controle para a primeira instrução após o loop. Portanto, essa instrução encerra a execução do loop atual. Vamos considerá-lo com mais detalhes no próximo artigo.
Lembre-se do nosso exemplo da fruta. Se não tivermos certeza da qualidade das maçãs, podemos alterar o código usando uma instrução continue :

while (numberOfApplesInBowl > 0) {
    apple = bowl.grabNextApple();
    numberOfApplesInBow--; // "--" is the decrement operator, which reduces the number of apples by one
    if (apple.isBad()) { // This method returns true for rotten apples
        apple.throwInGarbage();
        continue; // Continue the loop. Jump to evaluation of numberOfApplesInBowl > 0
    }
    arrangeInPie(apple.peel().slice());
}
A instrução continue geralmente é usada quando as instruções no corpo do loop precisam ser executadas se uma determinada condição for satisfeita. Por exemplo, podemos querer executar ações quando um sensor de hardware é acionado (caso contrário, simplesmente continuar o loop no qual fazemos as leituras do sensor) ou podemos querer calcular uma expressão apenas em determinadas iterações de um loop. Um exemplo do último caso pode ser visto em nosso uso de um loop while para calcular a soma dos cubos de números naturais cujo quadrado é menor que o número de números. Confuso? Confira o seguinte código:

public static void main(String[] args) {
    int sum = 0;  // Total amount
    int i = 0;  // Initial number in the series
    int count = 20;  // Number of numbers
    while (i <= count) {
        i++;  // Get the next number — "i++" is equivalent to "i = i + 1"
        if (i * i <= count)  // If the square of the number is less than
            continue;  // the number of numbers, then we won't calculate the sum
                            // Jump to the next number in the loop
        sum += i * i * i;  // Otherwise, we calculate the sum of the cubes of numbers
    }  // "sum += i * i * i" is notation that is equivalent to "sum = sum + i * i * i"
    System.out.println(sum);  // Print the result
}

Loop infinito

Essas instruções de ramificação são usadas com mais frequência em loops infinitos. Chamamos um loop de infinito se a condição booleana para sair do loop nunca for satisfeita. No código, parece algo assim:

while (true) {
    // Loop body 
}
Nesse caso, uma instrução break nos ajuda a sair do loop. Este tipo de loop é adequado quando se espera por condições externas determinadas fora do corpo do loop. Por exemplo, em sistemas operacionais ou jogos (sair do loop significa sair do jogo). Ou ao usar algoritmos que tentam, a cada iteração de um loop, melhorar algum resultado, mas limitam o número de iterações com base no tempo decorrido ou na ocorrência de um evento externo (por exemplo, damas, xadrez ou previsão do tempo). Lembre-se de que, em condições normais, loops infinitos não são desejáveis. Para demonstrar, vamos voltar à exponenciação:

public static void main(String[] args) {
    int base = 3; // The number that will be exponentiated
    int result = 1; // The result of exponentiation
    int exponent = 1; // The initial exponent
    while (true) {
        result = result * base;
        System.out.println(base + " raised to the power of " + exponent + " = " + result);
        exponent++;
        if (exponent > 10)
            break; // Exit the loop
    }
}
Saída do console:

3 raised to the power of 1 = 3
3 raised to the power of 2 = 9
3 raised to the power of 3 = 27
3 raised to the power of 4 = 81
3 raised to the power of 5 = 243
3 raised to the power of 6 = 729
3 raised to the power of 7 = 2187
3 raised to the power of 8 = 6561
3 raised to the power of 9 = 19683
3 raised to the power of 10 = 59049
Process finished with exit code 0

Loops aninhados

E agora chegamos ao nosso tópico final sobre loops. Lembre-se daquela torta de maçã (espero que você não esteja com fome no momento) e nosso loop de descascar maçã:
  1. Se houver maçãs na tigela, executamos as etapas 1.1 a 1.4:

    1. 1.1. Pegue uma maçã
    2. 1.2. Descasque e corte em fatias
    3. 1.3. Arrume as fatias de maçã na massa da torta em uma assadeira
    4. 1.4. Retorne ao passo 1.
Vamos descrever o processo de fatiamento com mais detalhes:
  1. Número de fatias = 0
  2. Contanto que o número de fatias seja < 12, execute as etapas 2.1 a 2.3

    1. 2.1. Corte outra fatia da maçã
    2. 2.2. Número de fatias++
    3. 2.3. Voltar para a etapa 2
E adicionaremos isso ao nosso algoritmo de criação de tortas:
  1. Se houver maçãs na tigela, executamos as etapas 1.1 a 1.6:

    1. 1.1. Pegue uma maçã
    2. 1.2. Descasque
    3. 1.3. Número de fatias = 0
    4. 1.4. Contanto que o número de fatias seja < 12, execute as etapas 1.4.1 a 1.4.3
      1. 1.4.1. Corte outra fatia da maçã
      2. 1.4.2. Número de fatias++
      3. 1.4.3. Voltar para a etapa 1.4
    5. 1.5. Arrume as fatias de maçã na massa da torta em uma assadeira
    6. 1.6. Retorne ao passo 1.
Agora temos um loop dentro de um loop. Construções como esta são muito comuns. Como exemplo final, vamos construir uma das tabuadas que aprendemos a amar no ensino fundamental.

 public static void main(String[] args) {
    // Print the second factors in a row
    System.out.println("    2  3  4  5  6  7  8  9"); 
    int i = 2;  // Assign the first factor to the variable
    while (i < 10) {  // First loop: execute as long as the first factor is less than 10
        System.out.print(i + " | ");  // Print the first factor at the beginning of the line
        int j = 2;  // The starting value of the second factor
        while (j < 10) { // Second loop: execute as long as the second factor is less than 10
            int product = i * j;  // Calculate the product of the factors
            if (product < 10)  // If the product is a single digit, then we print two spaces after the product
                System.out.print(product + "  ");
            else  // Otherwise, print the product and one space after it
                System.out.print(product + " ");
            j++;  // Increment the second factor by one
        }  // Go to the beginning of the second loop, i.e. "while (j < 10)"
        System.out.println();  // Move to the next line on the console
        i++;  // Increment the first factor by one
    } // Go to the beginning of the first loop, i.e. "while (i < 10)"
}
Saída do console:

    2  3  4  5  6  7  8  9
2 | 4 6 8 10 12 14 16 18
3 | 6 9 12 15 18 21 24 27
4 | 8 12 16 20 24 28 32 36
5 | 10 15 20 25 30 35 40 45
6 | 12 18 24 30 36 42 48 54
7 | 14 21 28 35 42 49 56 63
8 | 16 24 32 40 48 56 64 72
9 | 18 27 36 45 54 63 72 81
Process finished with exit code 0
Loops (em particular, a instrução while ) são um dos blocos de construção fundamentais do software. Ao resolver tarefas no CodeGym, você aprenderá todos os diferentes tipos de loops, entenderá suas complexidades e obterá habilidades práticas para usá-los.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION