Condições e laços em Java

Aprenda como um programa Java toma decisões e repete tarefas. Escreva condições com operadores relacionais e lógicos, escolha entre caminhos com if, cadeias de else if e expressões switch, e repita instruções com laços while, do-while e for, usando break e continue quando forem úteis. Depois, aplique os padrões comuns de laços para contar, somar, calcular médias, encontrar o maior valor, fazer buscas e imprimir tabelas, e verifique seus laços acompanhando cada passagem.

BásicoAula 2 de 11 do curso Curso de Programação orientada a objetos com Java

O que você vai aprender

  1. Construa condições verdadeiras ou falsas a partir de comparações e combine-as com operadores lógicos para que um programa teste exatamente a situação desejada.
    • Compare valores e armazene os resultados como booleanos
      Use os seis operadores relacionais com números e caracteres, guarde os resultados em variáveis boolean e compare cadeias de caracteres e números decimais corretamente.
    • Combine condições com &&, || e !
      Una e negue condições com os operadores lógicos, preveja seus resultados com tabelas-verdade e use a avaliação de curto-circuito e as leis de De Morgan para escrever testes corretos e legíveis.
  2. Faça um programa executar instruções diferentes conforme as condições, desde um único if até cadeias de else if, o operador condicional e switch.
    • Execute código condicionalmente com if e else
      Escreva instruções if e if-else com blocos corretos, evite os erros clássicos de chaves, ponto e vírgula e escopo, e aninhe decisões ou escolha um valor com o operador condicional.
    • Escolha um entre vários casos com cadeias de else-if
      Use cadeias de else if para escolher exatamente um entre vários resultados, ordene as condições corretamente e teste os valores-limite para que nenhum valor caia em uma lacuna ou em dois casos.
    • Selecione por valor com switch
      Use instruções switch e expressões switch para escolher pelo valor de uma variável, com casos de seta, vários rótulos por caso, default e yield, e reconheça a continuação entre casos na forma mais antiga com dois-pontos.
  3. Escreva laços while, do-while e for que sejam executados o número certo de vezes e parem quando devem, e controle-os com break e continue.
    • Repita enquanto uma condição for verdadeira com while
      Escreva laços while que comecem, sejam atualizados e parem corretamente, use while (true) com break para repetições sem duração definida e acompanhe um laço a cada passagem.
    • Execute o corpo pelo menos uma vez com do-while
      Use o laço do-while quando o corpo precisar ser executado antes do primeiro teste, como em verificações de entrada e menus, e evite suas armadilhas de escopo e ponto e vírgula.
    • Percorra intervalos de contagem com laços for
      Escreva laços for que contem em ordem crescente, decrescente e em passos, preveja quantas vezes eles serão executados, evite erros de uma unidade e escolha o tipo certo de laço para cada tarefa.
    • Encerre laços ou pule iterações com break e continue
      Encerre um laço antecipadamente com break, pule o restante de uma passagem com continue, saia de laços aninhados com um break com rótulo e mantenha fáceis de acompanhar os laços com saídas antecipadas.
  4. Reconheça e combine os padrões comuns de laços: contar e somar, encontrar valores extremos, fazer buscas, processar algarismos e aninhar laços, e verifique os laços por meio de rastreamento e testes.
    • Conte valores, some-os e calcule sua média
      Use contadores e acumuladores com entrada controlada por sentinela, calcule médias e porcentagens sem erros de divisão inteira e proteja-se contra entrada vazia e estouro.
    • Encontre valores extremos, faça buscas e processe algarismos
      Acompanhe o maior ou o menor valor encontrado até o momento, faça buscas com uma variável sinalizadora ou uma saída antecipada, teste se algum ou todos os valores atendem a uma condição e decomponha números algarismo por algarismo.
    • Aninhe laços, acompanhe sua execução e teste-os
      Escreva laços aninhados para tabelas e padrões, preveja quantas vezes o corpo interno será executado, acompanhe laços com uma tabela e teste-os com casos extremos para encontrar erros de uma unidade e laços infinitos.

Guia de estudo de Condições e laços em Java

4 capítulos

1

Construa condições verdadeiras ou falsas

Uma condição transforma uma pergunta sobre os dados do programa em um valor verdadeiro ou falso. Comparações permitem perguntar se um número atinge um limite ou se um texto corresponde a um comando; operadores lógicos permitem unir esses testes. Leia as partes de uma condição na ordem em que Java as avalia e depois verifique o resultado combinado. Assim, é possível expressar um intervalo, uma exceção ou uma verificação de proteção para uma divisão sem deixar que um pequeno erro de operador altere a regra.

1.1 Comparações e valores booleanos

Uma condição tem o tipo boolean: ela produz true ou false. Java precisa desse resultado explícito em uma condição de if ou de laço. Um inteiro sozinho não é uma condição, portanto while (count) não compila; count > 0 faz uma pergunta clara de resposta verdadeira ou falsa.

Compare números e caracteres
OperadorPergunta
<O valor à esquerda é menor?
<=Ele é menor ou igual?
>Ele é maior?
>=Ele é maior ou igual?
==Os valores são iguais?
!=Os valores são diferentes?

Com int a = 7; e int b = 10;, a < b e a != b são true, enquanto a >= b é false. Tipos numéricos diferentes podem ser comparados: 3 == 3.0 é true depois que Java faz uma conversão de ampliação do inteiro para double.

Uma comparação de char usa códigos numéricos Unicode. Por exemplo, 'a' < 'b' é true. O mesmo ocorre com 'Z' < 'a': seus códigos são 90 e 97. Nessa ordenação, todas as letras maiúsculas ASCII de A a Z precedem as minúsculas de a a z.

Armazene uma resposta útil
int age = 17;
boolean isAdult = age >= 18;
System.out.println(isAdult);

A comparação produz false, que é armazenado em isAdult e depois impresso. Um nome significativo permite que o código posterior diga diretamente if (isAdult).

Mantenha atribuição e comparação distintas. = armazena um valor; == compara valores. Para um inteiro, if (x = 5) falha porque a atribuição produz um inteiro. Para um booleano, if (done = true) compila, define done como true e executa o ramo. Para testar a variável sinalizadora existente, escreva if (done).

Compare texto e decimais calculados

Use command.equals("quit") para comparar os caracteres de uma cadeia de caracteres. O texto digitado como “quit” corresponde; “Quit” não corresponde. Use equalsIgnoreCase quando a diferença entre maiúsculas e minúsculas não importar e !command.equals("quit") para testar se o texto é diferente. O operador == verifica se as cadeias de caracteres se referem ao mesmo objeto, portanto não é adequado para comparar o conteúdo de uma entrada do usuário.

O formato binário de ponto flutuante não consegue armazenar muitas frações decimais exatamente. 0.1 + 0.2 produz 0.30000000000000004, portanto 0.1 + 0.2 == 0.3 é false. Uma comparação com tolerância verifica a distância entre os valores calculados:

double sum = 0.1 + 0.2;
boolean closeEnough = Math.abs(sum - 0.3) < 1e-9;

Aqui Math.abs torna a diferença não negativa; a pequena diferença está abaixo de 1e-9, portanto closeEnough é true. Escolha uma tolerância adequada à precisão exigida pelo cálculo. Comparações exatas de valores int não têm o problema de arredondamento em ponto flutuante.

Teste divisibilidade e intervalos

n % 3 == 0 testa se um inteiro é divisível por 3. Para números ímpares, use n % 2 != 0: o teste inclui valores ímpares negativos, pois -7 % 2 é -1.

Escreva cada lado de um teste de intervalo separadamente: 0 < x && x < 10. Java não consegue ler 0 < x < 10 como uma cadeia matemática: a primeira comparação já produz um booleano, que não pode ser comparado com 10.

Principais conclusões

  • Uma condição deve produzir um boolean.
  • Use = para atribuir e == para comparar valores numéricos.
  • Compare o conteúdo de cadeias de caracteres com equals ou equalsIgnoreCase.
  • Compare decimais calculados com uma tolerância adequada.
  • Use n % 2 != 0 para inteiros ímpares, incluindo os negativos.

1.2 Condições combinadas e avaliação de curto-circuito

Operadores lógicos combinam condições completas, verdadeiras ou falsas. Leia uma condição combinada como uma regra sobre os dados e depois teste valores que devem ser aceitos e valores que devem ser rejeitados.

Una e negue testes

&& significa e: ambas as partes devem ser verdadeiras. || significa ou: pelo menos uma parte deve ser verdadeira, inclusive quando ambas são. ! significa não e inverte um valor booleano.

| p | q | p && q | p || q | | --- | --- | --- | --- | | true | true | true | true | | true | false | false | true | | false | true | false | true | | false | false | false | false |

Uma temperatura confortável de 18 a 24 °C precisa dos dois limites: temp >= 18 && temp <= 24. Estar fora desse intervalo significa temp < 18 || temp > 24. Unir os limites internos com || aceita qualquer número: abaixo de 18, o teste do limite superior é verdadeiro e, acima de 24, o teste do limite inferior é verdadeiro.

Cada operando deve ser uma expressão booleana. Escreva x == 1 || x == 2, pois x == 1 || 2 coloca um inteiro onde um booleano é necessário. Para um inteiro, !x > 5 é inválido; !(x > 5) nega a comparação inteira.

Avalie apenas o necessário

Java avalia && e || da esquerda para a direita e usa a avaliação de curto-circuito quando a parte esquerda determina a resposta. Com &&, um lado esquerdo falso faz o lado direito ser ignorado. Com ||, um lado esquerdo verdadeiro faz o lado direito ser ignorado.

int total = 36;
int count = 0;
boolean largeAverage = count != 0 && total / count > 10;

A primeira comparação é falsa, portanto a divisão é ignorada e largeAverage passa a ser false. Inverta os operandos e a divisão ocorrerá antes da verificação de proteção; a divisão inteira por zero lança uma ArithmeticException. Coloque a verificação de segurança antes do cálculo que ela protege.

Torne o agrupamento visível

Da maior para a menor precedência, os operadores relevantes são !, comparações relacionais (<, <=, >, >=), comparações de igualdade (==, !=), && e depois ||. Assim, a || b && c é agrupado como a || (b && c). Quando a é verdadeiro e b e c são falsos, essa expressão é verdadeira; (a || b) && c é falsa. Os parênteses mostram qual regra você pretende usar.

As leis de De Morgan deslocam uma negação por uma condição combinada:

  • !(p && q) equivale a !p || !q.
  • !(p || q) equivale a !p && !q.

Negue cada parte e troque o operador que as une. Aplicar isso ao intervalo de temperatura mostra que !(temp >= 18 && temp <= 24) equivale a temp < 18 || temp > 24.

Expresse uma regra com uma exceção

Um ano bissexto no calendário gregoriano é divisível por 4, exceto que um ano de início de século deve ser divisível por 400:

boolean leap = (year % 4 == 0 && year % 100 != 0)
        || year % 400 == 0;

A primeira parte aceita 2024. Ela rejeita 1900 porque 1900 é um ano de início de século; o teste final aceita 2000 porque ele é divisível por 400. O ano 2026 não atende a nenhuma das partes.

Booleanos com nomes ajudam a tornar testes mais longos claros, como isWeekend || isHoliday. Para dois booleanos, ^ é o OU exclusivo: exatamente um operando deve ser verdadeiro, como em !=. Os operadores simples & e | também calculam o e/ou booleano, mas avaliam ambos os operandos; use && e || para condições com curto-circuito.

Principais conclusões

  • && exige ambas as condições; || exige pelo menos uma.
  • Uma verificação de proteção com curto-circuito deve vir antes da expressão que protege.
  • && tem precedência maior que ||; os parênteses podem alterar o resultado.
  • As leis de De Morgan negam ambas as partes e trocam && por || e vice-versa.
  • Cada lado de um operador lógico deve ser uma expressão booleana completa.
  • Os operadores simples & e | avaliam ambos os operandos.
2

Escolha o caminho que um programa segue

Uma decisão direciona a execução por um caminho selecionado. Um único teste pode habilitar uma ação, um par de ramos pode escolher entre duas ações e uma cadeia pode atribuir um resultado a partir de vários intervalos. Quando a escolha depende de valores exatos de uma variável, switch oferece outra forma clara. Acompanhar o caminho significa verificar quais condições são alcançadas, qual ramo é executado e quais variáveis permanecem disponíveis depois.

2.1 Ramos, blocos e escolha de valores

Um if executa um bloco quando sua condição é verdadeira. Um if com else escolhe exatamente um de dois blocos. Depois que o bloco escolhido termina, a execução continua com a instrução seguinte.

Escolha um caminho
int age = 16;
if (age >= 18) {
    System.out.println("Adult ticket");
} else {
    System.out.println("Youth ticket");
}
System.out.println("Next customer");

A condição é falsa, portanto a saída é “Youth ticket”, seguida de “Next customer”. A última instrução não pertence a nenhum dos ramos. Coloque a condição booleana entre parênteses e as instruções de cada ramo entre chaves.

Sem chaves, apenas a próxima instrução pertence a um if. A indentação não agrupa código. Neste exemplo com erro, a segunda mensagem aparece para qualquer pontuação:

if (score < 50)
    System.out.println("Not passed");
    System.out.println("Try again");

Chaves ao redor das duas instruções de impressão tornam ambas condicionais. Outro erro é um ponto e vírgula imediatamente após a condição: if (x > 10); tem um corpo vazio. Um bloco que venha em seguida é executado independentemente, e um else depois desse bloco independente não tem um if correspondente.

Mantenha um resultado disponível

Uma variável declarada dentro de um bloco só é visível dentro dele. Declare um resultado antes dos ramos quando o código posterior precisar dele:

String ticket;
if (age >= 18) {
    ticket = "Adult ticket";
} else {
    ticket = "Youth ticket";
}
System.out.println(ticket);

Ambos os caminhos possíveis atribuem um valor a ticket, portanto imprimi-la depois é válido. Se apenas o ramo verdadeiro atribuísse um valor a ela, Java rejeitaria a leitura posterior: a variável poderia não ter sido inicializada. Declarar ticket separadamente dentro de cada ramo também deixaria ticket indisponível depois da decisão.

Coloque uma decisão dentro de outra

Um if aninhado só executa seu teste quando a execução chega ao ramo que o contém:

if (hasTicket) {
    if (age < 12) {
        System.out.println("Child seat");
    } else {
        System.out.println("Standard seat");
    }
} else {
    System.out.println("Buy a ticket first");
}

Uma pessoa sem ingresso chega ao else externo; a verificação de idade é ignorada. Se ambos os testes aninhados apenas condicionam a mesma ação e nenhum deles tem else, eles podem se tornar if (hasTicket && age < 12).

A regra do else pendente associa um else ao if mais próximo ainda sem correspondência. Sem chaves, alinhá-lo visualmente com um if externo não altera essa regra. Para um teste externo de x positivo seguido de um teste interno de y positivo, o próximo else pertence ao teste de y. São necessárias chaves ao redor da decisão interna completa quando o else deve pertencer ao teste externo.

Escolha um valor com ?:

O operador condicional escolhe um de dois valores:

int n = 7;
String label = n % 2 == 0 ? "even" : "odd";

A condição é falsa, portanto a expressão produz “odd”. Sua forma é condition ? valueIfTrue : valueIfFalse. Use-o para uma escolha curta de valor; use um if quando os ramos executarem várias ações. Expressões condicionais aninhadas logo tornam difícil acompanhar o caminho escolhido.

Principais conclusões

  • As chaves agrupam todas as instruções que pertencem a um ramo.
  • Um else se associa ao if mais próximo ainda sem correspondência.
  • Um resultado necessário após uma decisão deve estar no escopo e receber um valor em todos os caminhos que chegam ao seu uso.
  • ?: escolhe um valor entre duas expressões.

2.2 Casos ordenados e valores-limite

Uma cadeia de else if testa condições em ordem e seleciona a primeira verdadeira. Depois que esse ramo é executado, as condições restantes são ignoradas. Um else final trata os valores restantes; sem ele, a cadeia pode não executar nenhuma ação.

Ordene limiares sobrepostos

Para pontuações de 0 a 100, teste primeiro a nota mais alta:

String grade;
if (score >= 90) {
    grade = "A";
} else if (score >= 80) {
    grade = "B";
} else if (score >= 70) {
    grade = "C";
} else if (score >= 60) {
    grade = "D";
} else {
    grade = "F";
}

Para 85, o primeiro teste falha e o segundo é satisfeito. O programa atribui “B” sem verificar os limiares restantes. Chegar a score >= 80 já significa que a pontuação é menor que 90, portanto um limite superior adicional é desnecessário.

Se score >= 60 aparecesse primeiro, toda pontuação de aprovação receberia “D”. Trabalhe do caso correspondente mais restritivo para os mais abrangentes. Essa regra de ordenação importa porque várias condições podem ser verdadeiras, embora apenas um ramo seja executado.

Trate primeiro o caso combinado

FizzBuzz tem um caso especial em que duas regras se sobrepõem: múltiplos de 3 e de 5 precisam de “FizzBuzz”. Teste esse caso antes de qualquer um dos testes individuais de divisibilidade:

if (n % 15 == 0) {
    System.out.println("FizzBuzz");
} else if (n % 3 == 0) {
    System.out.println("Fizz");
} else if (n % 5 == 0) {
    System.out.println("Buzz");
} else {
    System.out.println(n);
}

O teste % 15 == 0 aceita 30; 9 chega a “Fizz”, 10 chega a “Buzz” e 7 chega ao ramo final. Começar com % 3 == 0 aceitaria 30 cedo demais e imprimiria apenas “Fizz”.

Escolha um resultado ou várias ações

Instruções if separadas são decisões independentes. Com x = 15, um if (x > 10) pode imprimir “big” e um if (x > 0) seguinte também pode imprimir “positive”. Uni-los com else if torna o segundo teste inalcançável sempre que o primeiro for verdadeiro. Use testes independentes quando ambas as ações puderem ser necessárias; use uma cadeia para selecionar um resultado.

Verifique limites e valores inválidos

Uma cadeia para temperaturas inteiras com temp < 10, depois temp > 10 && temp < 25 e depois temp >= 25 deixa de fora exatamente 10. Substitua o segundo teste por temp < 25: chegar a ele já significa que o primeiro teste falhou, portanto o valor é pelo menos 10. Um else final trata então 25 e valores maiores.

Para cada limiar, experimente o valor imediatamente abaixo dele, o próprio limiar e o valor imediatamente acima dele. Para a cadeia de notas, 89, 90 e 91 revelam se o limite de A está incluído corretamente. Teste também os limites gerais.

Valide uma pontuação antes de atribuir uma nota: coloque score < 0 || score > 100 primeiro e informe “Invalid score” nesse caso. Os ramos posteriores operam então apenas sobre pontuações válidas; 150 não pode receber “A” acidentalmente. A validação é um primeiro caso separado, não uma correção depois que a nota já foi escolhida.

Principais conclusões

  • A primeira condição verdadeira em uma cadeia seleciona o único ramo executado.
  • Coloque casos sobrepostos mais restritos antes dos mais abrangentes.
  • Use instruções if separadas quando várias ações puderem se aplicar.
  • Teste os valores em cada limiar e próximos a ele.
  • Rejeite entradas inválidas antes de classificar as válidas.

2.3 Casos de switch e resultados de expressões

Um switch seleciona um caso comparando um valor com rótulos fixos. Ele é adequado para comandos nomeados e escolhas numeradas. Use uma cadeia de else if quando a escolha depender de um intervalo ou de várias variáveis.

Encontre valores exatos

Um switch por valor aceita seletores char, byte, short, int, seus tipos empacotadores, String e tipos enum. Sem recursos em prévia, seletores long, float, double e boolean não são aceitos. Os rótulos devem ser constantes: uma condição como score >= 90 não é um rótulo de valor.

switch (day) {
    case 1, 2, 3, 4, 5 -> System.out.println("Weekday");
    case 6, 7 -> System.out.println("Weekend");
    default -> System.out.println("Invalid day");
}

Um caso com seta executa apenas seu próprio código, sem continuação para o caso seguinte. Vírgulas agrupam vários rótulos para uma ação. Um dia igual a 6 imprime “Weekend”; um dia igual a 9 não corresponde a nenhum valor listado e imprime “Invalid day”.

Rótulos de String correspondem a conteúdos exatos, com distinção entre maiúsculas e minúsculas. Um comando “Start” não corresponde a case "start". Um rótulo duplicado é um erro de compilação, e um mesmo switch não pode misturar casos com seta e casos com dois-pontos.

Produza um valor

Uma expressão switch calcula um resultado:

int days = switch (month) {
    case 1, 3, 5, 7, 8, 10, 12 -> 31;
    case 4, 6, 9, 11 -> 30;
    case 2 -> 28;
    default -> 0;
};

Em um ano não bissexto, o mês 9 produz 30, o mês 2 produz 28 e o mês inválido 13 produz 0. O ponto e vírgula após a chave de fechamento encerra a declaração da variável.

Uma expressão deve ser exaustiva: cada valor possível do seletor deve ter um resultado. Para estes exemplos com int e String, inclua default. Uma instrução switch por valor pode omitir default; nesse caso, um valor sem correspondência não executa nenhum caso. Uma expressão que produz um valor não pode simplesmente deixar de produzir seu resultado.

Forneça um resultado a um bloco com yield

Um caso que faz cálculos antes de escolher seu valor precisa de um bloco:

int days = switch (month) {
    case 2 -> {
        boolean leap = (year % 4 == 0 && year % 100 != 0)
                || year % 400 == 0;
        yield leap ? 29 : 28;
    }
    case 4, 6, 9, 11 -> 30;
    case 1, 3, 5, 7, 8, 10, 12 -> 31;
    default -> 0;
};

yield fornece o valor do caso à expressão switch. Fevereiro produz 29 em 2024 e 28 em 2026. Uma única expressão após uma seta, como case 2 -> 28;, não precisa de yield.

Leia a forma mais antiga com dois-pontos
switch (level) {
    case 1:
        System.out.println("Bronze");
    case 2:
        System.out.println("Silver");
        break;
    case 3:
        System.out.println("Gold");
        break;
}

Para o nível 1, a execução entra no primeiro caso e continua no segundo, imprimindo tanto “Bronze” quanto “Silver”. Isso é a continuação entre casos: um rótulo com dois-pontos não interrompe a execução. break encerra o switch. Rótulos com dois-pontos em sequência podem compartilhar uma ação deliberadamente; a falta de um break após uma ação pode executar a próxima acidentalmente.

Um switch de char pode agrupar 'a', 'e', 'i', 'o', 'u' em um resultado “vowel”, com default produzindo “other”. O mesmo princípio de valor exato se aplica a caracteres, comandos e escolhas numéricas.

Principais conclusões

  • Use switch para rótulos fixos de um seletor.
  • Casos com seta não continuam para o caso seguinte.
  • Uma expressão switch deve produzir um resultado para cada valor possível do seletor.
  • Um caso com bloco fornece o resultado da expressão com yield.
  • Um caso com dois-pontos pode continuar para o seguinte sem break.
  • Casos de String correspondem a conteúdos exatos, com distinção entre maiúsculas e minúsculas.
3

Controle a repetição e a parada

A repetição depende tanto de uma condição quanto de uma alteração no estado do programa. Acompanhe um laço desde seus valores iniciais, passando pelo teste, pelo corpo e pela atualização, para ver quando ele para. As três formas de laço colocam essas partes em posições diferentes: antes do corpo, depois dele ou juntas em um cabeçalho. Saídas antecipadas e passagens puladas acrescentam opções úteis, mas também tornam importante acompanhar a ordem de execução com cuidado.

3.1 Testes do laço while e alterações de estado

Um laço while testa sua condição antes de cada passagem. Se a condição for verdadeira, Java executa o corpo e retorna ao teste. Se for falsa, a execução continua depois do laço. Um primeiro teste falso significa zero passagens.

Acompanhe início, teste, corpo e atualização
int i = 1;
while (i <= 5) {
    System.out.println(i);
    i++;
}

O valor inicial é 1. Cada passagem imprime o valor atual e depois o incrementa. A quinta passagem imprime 5 e altera i para 6. O teste seguinte é falso, portanto o laço termina. Há cinco execuções do corpo, mas seis testes da condição: um antes de cada passagem e um teste falso final.

Um laço de contagem precisa de um valor inicial, um teste e uma atualização que o aproxime da parada. Omita i++ e esse laço imprimirá 1 para sempre. Um ponto e vírgula indevido é outra armadilha: em while (i <= 5);, a instrução vazia é o corpo. Quando i começa dentro do intervalo, o bloco posterior nunca é alcançado e não pode atualizá-lo.

Pare quando um limite for ultrapassado

A igualdade costuma ser um teste de parada frágil. Começar em 0 e somar 3 passa por 0, 3, 6, 9, 12 e assim por diante. O teste i != 10 não consegue perceber que 10 foi ultrapassado, pois 10 é pulado. O teste i < 10 termina depois de processar 9. Escolha um limite que corresponda à direção da atualização.

Alguns laços se repetem um número desconhecido de vezes. Por exemplo:

int amount = 1;
int days = 0;
while (amount < 1000) {
    amount *= 2;
    days++;
}

Cada passagem dobra a quantidade e conta um dia. Após nove passagens, ela é 512; após dez, é 1024. O teste falso em 1024 deixa days igual a 10. Um laço pode terminar acima de seu limiar quando a atualização avança em passos maiores.

Leia antes de decidir se deve parar
while (true) {
    String line = scanner.nextLine();
    if (line.equals("stop")) {
        break;
    }
    System.out.println("You wrote: " + line);
}

Aqui scanner é o Scanner de entrada. O laço lê uma linha, verifica se é “stop” e exibe apenas as linhas comuns. O comando de parada é lido, mas não é processado. while (true) precisa de uma saída alcançável para terminar; um laço que continua se repetindo sem sair é um laço infinito.

Registre as alterações de estado

Considere um produto:

int n = 3;
int product = 1;
while (n > 0) {
    product *= n;
    n--;
}
Momentoproductn
Antes do laço13
Após a passagem 132
Após a passagem 261
Após a passagem 360

A multiplicação usa o valor anterior de n, e o decremento vem depois. Mover o decremento para antes da multiplicação alteraria os valores multiplicados.

Declare um resultado acumulado antes do laço para que ele seja mantido de uma passagem para outra. Uma variável declarada dentro do corpo é criada novamente sempre que a execução chega à sua declaração. Imprima dentro do corpo para ver os resultados intermediários; imprima após a chave de fechamento para mostrar o resultado final uma vez.

Principais conclusões

  • Um laço while pode ser executado zero vezes.
  • Acompanhe a condição antes de cada passagem, incluindo o teste falso final.
  • Laços de contagem precisam de uma atualização que avance em direção a um limite de parada.
  • Um comando de parada deve ser verificado antes que sua entrada seja processada.
  • Mantenha os resultados acumulados fora do corpo do laço.

3.2 Verificações de entrada com do-while

Um laço do-while executa o corpo antes de verificar se outra passagem é necessária. Use-o quando a primeira ação precisar acontecer, como mostrar um menu ou pedir um valor de entrada.

Teste após a primeira ação
int i = 10;
do {
    System.out.println(i);
    i++;
} while (i < 5);

O corpo imprime 10 e incrementa i para 11. Só então Java testa i < 5. A condição é falsa, portanto não há uma segunda passagem. Um laço while (i < 5) que começasse em 10 não imprimiria nada.

O ponto e vírgula após o while (...) final é obrigatório. Ele encerra a instrução do-while. Isso é diferente do ponto e vírgula acidental após um cabeçalho while com teste no início, que cria um corpo de laço vazio.

Repita enquanto a entrada for inválida
int rating;
do {
    System.out.print("Rating (1-5): ");
    rating = Integer.valueOf(scanner.nextLine());
} while (rating < 1 || rating > 5);

A solicitação aparece antes da primeira verificação, para que o usuário possa fornecer o valor a ser verificado. Com as entradas 7, depois 0 e depois 4, as duas primeiras avaliações da condição são verdadeiras e provocam outra solicitação. A última é falsa, portanto o laço termina com rating igual a 4.

A condição descreve a continuação, não a aceitação. Uma avaliação válida satisfaz rating >= 1 && rating <= 5. O laço se repete enquanto essa afirmação é falsa, o que as leis de De Morgan reescrevem como rating < 1 || rating > 5. Uma conjunção entre esses limites externos nunca seria verdadeira: um número não pode estar abaixo de 1 e acima de 5 ao mesmo tempo.

Declare a variável verificada antes do bloco

A chave de fechamento encerra o escopo do corpo antes que a condição seja avaliada. Uma declaração como int rating dentro do bloco do ficaria, portanto, indisponível na condição final. Declare-a antes de do e atribua a entrada dentro do corpo. A atribuição sempre é executada antes do primeiro teste.

A mesma posição importa quando o valor aceito é usado depois. rating permanece no escopo após todo o laço e agora contém o último valor lido.

Mantenha um menu aberto
String choice;
do {
    System.out.println("a: show status, q: quit");
    choice = scanner.nextLine();
    if (choice.equals("a")) {
        System.out.println("Ready");
    }
} while (!choice.equals("q"));

Cada passagem exibe o menu e lê uma escolha. Digitar “a” imprime “Ready” e repete. Digitar “q” pula a ação e encerra o laço na condição. Um comando desconhecido também provoca repetição porque não é “q”.

Quando seu corpo não contém um continue direcionado ao laço, um do-while pode ser reescrito como while (true) com um break no final que verifica a condição negada. Um continue exige cuidado especial nessa reescrita: no do-while original, ele salta para a condição, enquanto em um laço while-true ele salta para o início e pode pular esse teste acrescentado ao final.

Principais conclusões

  • O corpo de um do-while é executado antes do primeiro teste.
  • O ponto e vírgula final é obrigatório.
  • Declare uma variável fora do corpo quando a condição precisar dela.
  • Para validação de entrada, repita enquanto o valor for inválido.

3.3 Intervalos e limites do laço for

Um laço for reúne o controle de uma tarefa de contagem em um cabeçalho. Ele é útil quando você conhece o intervalo ou o número de passagens antes do início da repetição.

Leia o cabeçalho na ordem de execução
for (int i = 1; i <= 5; i++) {
    System.out.println(i);
}

A inicialização é executada uma vez, definindo i como 1. Java testa i <= 5, executa o corpo se a condição for verdadeira, executa i++ e volta ao teste. A atualização é escrita no cabeçalho, mas é executada depois do corpo. O teste falso final encerra o laço.

Para uma contagem comum, i++ e ++i têm o mesmo efeito na posição de atualização porque o valor de nenhuma das expressões é usado. Mantenha as alterações do contador no cabeçalho para que a sequência seja fácil de prever.

Escolha o primeiro e o último valor
CabeçalhoValores usados pelo corpoPassagens
int i = 0; i < 5; i++0 a 45
int i = 0; i <= 5; i++0 a 56
int i = 10; i >= 1; i--10 a 110
int i = 0; i <= 20; i += 50, 5, 10, 15, 205

Para passos crescentes de uma unidade com o final pelo menos igual ao início, um limite final exclusivo produz final menos início passagens; um limite final inclusivo acrescenta uma. Passos maiores exigem listar ou contar os valores efetivamente alcançados. Um laço decrescente deve testar na direção correspondente: começar em 10 com i <= 1 produz zero passagens.

Um erro de uma unidade inclui ou exclui um limite indevidamente. Para imprimir de 1 a 10, i < 10 deixa 10 de fora; use i <= 10. Verifique o primeiro valor do corpo, o último valor do corpo e o primeiro valor que não satisfaz a condição.

Construa um resultado ao longo de um intervalo
int sum = 0;
for (int i = 1; i <= 100; i++) {
    sum += i;
}
System.out.println(sum);

O corpo soma cada inteiro uma vez, terminando com 5050. Um produto começa de forma diferente: inicialize product em 1 antes de multiplicar por 1 a 5. Isso produz 120; começar em 0 manteria o produto em 0 após cada multiplicação.

Observe o escopo e os corpos vazios

Um contador declarado no cabeçalho existe durante todo o laço, mas não depois de sua chave de fechamento. Declare-o antes se o código posterior precisar de seu valor final.

Um ponto e vírgula imediatamente após o cabeçalho é um corpo vazio. Em for (int i = 0; i < 3; i++);, a instrução vazia é executada três vezes. Um bloco seguinte que imprime “Hello” é executado uma vez depois do laço, não três. As chaves devem vir diretamente após o cabeçalho.

Qualquer parte do cabeçalho pode ser omitida. for (;;) { ... } não tem condição de parada e se comporta como while (true); ele precisa de uma saída como break para terminar.

Selecione o laço mais claro
TarefaForma útilMotivo
Percorrer um intervalo conhecidoforInício, limite e passo ficam juntos.
Repetir até uma entrada ou um estado mudarwhileO teste pode impedir a primeira passagem.
Perguntar primeiro e depois verificardo-whileA primeira execução do corpo é obrigatória.

As formas podem expressar a mesma repetição, mas as reescritas devem preservar a ordem dos testes e das atualizações, incluindo o que um continue pula.

Principais conclusões

  • Um laço for executa a inicialização uma vez e depois o teste, o corpo e a atualização.
  • Verifique o início, o último valor incluído e a contagem de passagens.
  • Um contador declarado no cabeçalho fica indisponível depois do laço.
  • Use for para intervalos, while para mudanças de estado e do-while para uma primeira passagem obrigatória.
  • Um ponto e vírgula após um cabeçalho for cria um corpo vazio.

3.4 Saídas antecipadas e passagens puladas

Uma saída antecipada pode interromper a repetição assim que sua tarefa estiver concluída. Uma passagem pulada pode deixar de executar um trabalho indesejado enquanto mantém o laço em andamento. Acompanhe seus destinos com cuidado: break e continue têm funções diferentes.

Encerre uma busca com break
for (int n = 51; n <= 100; n++) {
    if (n % 7 == 0) {
        System.out.println(n);
        break;
    }
}

Os valores de 51 a 55 não passam no teste de divisibilidade. O próximo valor, 56, é impresso e break sai do laço imediatamente. A atualização não é executada após esse break. Sem ele, múltiplos posteriores como 63 e 70 também seriam impressos.

Um break sem rótulo se aplica ao laço ou switch mais próximo que o contém. A execução continua depois dessa estrutura, não depois do programa inteiro.

Pule com continue
for (int i = 1; i <= 10; i++) {
    if (i % 3 == 0) {
        continue;
    }
    System.out.print(i + " ");
}

Para 3, 6 e 9, continue pula a instrução de impressão. Em um laço for, a atualização do cabeçalho ainda é executada, seguida do teste da condição. A saída contém 1, 2, 4, 5, 7, 8 e 10.

Em um while ou do-while, continue vai para a condição. Qualquer atualização abaixo dele no corpo é pulada. Se um contador de while começar em 0 e a primeira ação for if (i % 3 == 0) { continue; }, um i++ posterior no corpo nunca será alcançado. O contador permanece em 0 e o laço se repete para sempre. Mova a atualização necessária para antes de cada caminho que a pula ou use um cabeçalho for para manter a atualização automática.

Saia de laços aninhados deliberadamente

Um break comum dentro de um laço interno encerra apenas esse laço interno. Um rótulo pode indicar um laço externo como destino da saída:

outer:
for (int a = 1; a <= 10; a++) {
    for (int b = 1; b <= 10; b++) {
        if (a * b == 24 && a + b == 10) {
            System.out.println("Found " + a + " and " + b);
            break outer;
        }
    }
}

A busca percorre os pares em ordem. Em a = 4 e b = 6, ambos os testes são satisfeitos e o break com rótulo sai dos dois laços. continue outer seguiria para a atualização do laço externo e depois para seu próximo teste.

Distinga saídas de switch de saídas de laço

Em um laço de menu que contém um switch na forma com dois-pontos, break dentro de um caso encerra o switch. Ele não encerra por si só o laço ao redor. Um padrão claro define uma variável sinalizadora do laço como false no caso de saída e depois usa break para sair do switch. O laço termina quando sua próxima verificação da condição encontra a variável sinalizadora falsa. Casos com seta não precisam de break para impedir a continuação entre casos.

Break sem rótulo é permitido dentro de um laço ou switch; continue é permitido dentro de um laço. Colocá-los em outro lugar causa falha de compilação. Mantenha a regra normal de parada na condição do laço quando ela couber ali. Use while (true) com um break quando o teste de parada naturalmente pertencer a um ponto depois da leitura da entrada, mas antes de seu processamento. Várias saídas podem ser úteis, mas cada caminho adicional acrescenta estado a acompanhar durante o rastreamento.

Principais conclusões

  • break sai imediatamente da estrutura à qual se aplica.
  • O continue de um laço for ainda executa a atualização do cabeçalho.
  • O continue de um laço while pode pular uma atualização necessária do corpo.
  • Uma saída comum afeta a estrutura válida mais próxima.
  • Um break com rótulo pode sair de um laço externo.
  • Um break de switch não sai diretamente do laço ao redor.
4

Construa e verifique laços úteis

Um laço se torna útil quando mantém apenas as informações de que um problema precisa: uma contagem, uma soma acumulada, um melhor valor ou uma variável sinalizadora que registra uma correspondência. Combinar esses pequenos padrões resolve tarefas de processamento de entrada e de busca. Laços aninhados estendem a repetição a linhas e colunas. Acompanhe os valores que mudam, mantenha o estado no escopo correto e use entradas vazias e casos de valor-limite para verificar se o resultado descreve todos os dados.

4.1 Contagens, somas e médias acumuladas

Um contador registra quantos valores atendem a uma condição. Um acumulador combina valores em um resultado acumulado. Declare ambos antes do laço para que cada passagem continue o trabalho anterior.

Inicialize conforme a operação

Use int count = 0; e incremente quando um item atender à condição. Uma soma começa em 0 e usa sum += value;. Um produto começa em 1, pois multiplicar um 0 inicial eliminaria todos os fatores posteriores. Inicializar um total dentro do corpo o reinicia a cada passagem.

Para um intervalo, o passo do laço pode selecionar os valores: somar os inteiros pares de 2 a 100 em passos de 2 produz 2550. Ou coloque uma condição dentro do laço. Contar os números de 1 a 100 divisíveis por 3 ou por 5 produz 47: os seis múltiplos de 15 devem ser contados apenas uma vez.

Interrompa a entrada antes de somá-la

Uma sentinela é um valor especial de entrada que encerra a leitura. Ela não é um valor comum dos dados:

int sum = 0;
int count = 0;
while (true) {
    int number = Integer.valueOf(scanner.nextLine());
    if (number == 0) {
        break;
    }
    sum += number;
    count++;
}

Para a entrada 12, 7, 5, 0, a soma passa por 12, 19 e 24. A contagem chega a 3. O 0 final aciona o break antes que qualquer uma das variáveis mude. Contá-lo criaria um quarto item e produziria uma média incorreta, embora somar zero não altere a soma.

Divida somente após verificar a contagem
if (count > 0) {
    double average = (double) sum / count;
    System.out.println(average);
} else {
    System.out.println("No numbers entered");
}

O exemplo imprime 8.0. Com operandos inteiros, a divisão descarta a parte fracionária: 25 / 4 é 6. Converta antes de dividir para obter 6,25: (double) sum / count. Fazer a conversão explícita depois, (double) (sum / count), apenas converte o resultado já truncado para 6,0.

Se a sentinela chegar primeiro, a contagem será 0. A divisão inteira por zero lança uma ArithmeticException; uma soma em ponto flutuante igual a zero dividida por zero produz NaN. A verificação da contagem impede que uma entrada vazia produza uma média sem sentido.

Acompanhe vários resultados em uma passagem

Para as pontuações 55, 72, 90, 48 e 81, uma nota mínima de 60 produz cinco pontuações e três aprovações. Mantenha um contador total para cada pontuação e um contador de aprovações dentro da condição de aprovação. 100.0 * passed / total produz 60,0 por cento; 100.0 faz a aritmética usar ponto flutuante. Verifique também se o total é positivo antes dessa divisão.

O local da impressão muda o que é mostrado. Distâncias de 5, 3 e 8 km produzem totais acumulados de 5, 8 e 16 km quando impressos dentro do laço após a adição. Imprimir depois mostra apenas os 16 km finais.

Escolha um tipo grande o suficiente para o total

O máximo de int é 2.147.483.647. Somar todos os inteiros de 1 a 100.000 deve produzir 5.000.050.000, mas um int retorna ao valor 705.082.704 sem informar um erro. long sum = 0; armazena essa soma corretamente; o máximo de long é cerca de 9,2 × 10¹⁸. Fazer uma conversão de ampliação depois de o resultado já ter sofrido estouro não pode recuperar o valor perdido.

Principais conclusões

  • Inicialize uma soma ou contagem em 0 e um produto em 1.
  • Exclua a sentinela tanto da soma quanto da contagem.
  • Converta um operando antes da divisão para preservar a parte fracionária.
  • Proteja médias e porcentagens contra uma entrada vazia.
  • Mantenha a atualização de cada contador junto à condição que ele conta.
  • Use um tipo com capacidade suficiente antes de acumular um total grande.

4.2 Melhores valores, buscas e algarismos

Alguns laços guardam um melhor valor; outros guardam se uma correspondência ocorreu. Escolha o estado inicial de modo que ele represente a situação corretamente antes e depois de cada passagem.

Mantenha o melhor valor encontrado até o momento

Para acompanhar um máximo, substitua-o somente quando o valor atual for maior: if (value > max) { max = value; }. Começando pela primeira leitura, as temperaturas 14, 19, 11, 23 e 17 °C deixam máximos sucessivos de 14, 19, 19, 23 e 23 °C. Um mínimo usa <.

Inicializar um máximo em 0 falha com dados totalmente negativos: -5, -2 e -9 deixariam incorretamente 0 como resultado. Inicialize a partir de uma leitura real ou comece com Integer.MIN_VALUE para um máximo int e Integer.MAX_VALUE para um mínimo int. Informe que não há resultado quando não houver leituras.

Para registrar uma posição, atualize-a no mesmo ramo que o valor. Um > estrito mantém o primeiro máximo em caso de empate; >= o substitui novamente e mantém o último.

Pare após encontrar uma correspondência
int n = 1;
while (n * n <= 500) {
    n++;
}

Em 22, o quadrado é 484, portanto outra passagem é executada. Em 23, ele é 529 e a condição falha. O laço encontrou o menor inteiro positivo cujo quadrado é maior que 500. Uma busca com limites pode, em vez disso, testar cada candidato em um laço for e usar break na primeira correspondência.

Para uma pergunta com algum, comece com uma variável sinalizadora falsa e torne-a verdadeira ao encontrar uma correspondência. Para uma pergunta com todos, comece com ela verdadeira e torne-a falsa ao encontrar um contraexemplo. Não reinicie nenhuma das duas em um ramo else para valores posteriores: uma leitura posterior sem correspondência não apaga, por exemplo, uma leitura negativa anterior.

Teste se há um divisor

Um número primo é pelo menos 2 e não tem divisor de 2 até uma unidade a menos que ele mesmo. Para um inteiro positivo pequeno, uma verificação mais curta testa divisores apenas até sua raiz quadrada:

int n = 91;
boolean isPrime = n >= 2;
for (int d = 2; d * d <= n; d++) {
    if (n % d == 0) {
        isPrime = false;
        break;
    }
}

Os dois fatores de um par não podem ser ambos maiores que a raiz quadrada. Para 91, o divisor 7 produz resto zero e muda a variável sinalizadora para falsa. Para 97, nenhum divisor de 2 a 9 o divide, portanto a variável sinalizadora permanece verdadeira. Valores abaixo de 2 começam com a variável sinalizadora falsa. Para valores int positivos grandes, use d <= n / d para evitar estouro em d * d.

Remova um algarismo decimal por passagem

Para um inteiro não negativo, % 10 extrai o último algarismo e a divisão inteira / 10 o remove:

int n = 4072;
int sum = 0;
while (n > 0) {
    sum += n % 10;
    n /= 10;
}

Os algarismos são 2, 7, 0 e 4, produzindo 13. A variável de trabalho n termina em 0. Para inverter os algarismos, atualize reversed = reversed * 10 + n % 10; antes de remover o algarismo; 1234 se torna 4321 quando o resultado cabe no tipo escolhido.

Para contar algarismos, zero precisa de uma passagem mesmo que n > 0 comece falso. Use um do-while que incremente a contagem e divida n por 10. Ele conta um algarismo para 0 e a quantidade habitual para valores positivos.

Principais conclusões

  • Inicialize um valor extremo a partir de dados reais ou de um limite adequado do tipo.
  • Atualize a posição de um valor extremo junto com seu valor.
  • Mantenha uma variável sinalizadora de busca verdadeira após encontrar uma correspondência para “algum” ou falsa após encontrar um contraexemplo para “todos”.
  • Um teste de número primo não precisa de divisores acima da raiz quadrada.
  • Para inteiros não negativos, % 10 extrai um algarismo e / 10 o remove.
  • A contagem dos algarismos de zero precisa de uma primeira passagem obrigatória.

4.3 Trabalho aninhado, rastreamentos e casos de teste

Laços aninhados repetem uma repetição inteira a cada passagem externa. Eles são úteis para linhas, colunas, tabelas e formas. O laço interno deve começar novamente sempre que o laço externo chegar a ele.

Imprima uma linha e depois encerre-a
for (int row = 1; row <= 3; row++) {
    for (int col = 1; col <= 5; col++) {
        System.out.print(row * col + "\t");
    }
    System.out.println();
}

A primeira linha contém 1, 2, 3, 4, 5; a segunda contém 2, 4, 6, 8, 10; a terceira contém 3, 6, 9, 12, 15. O print interno cria colunas em uma linha; o println após o laço interno encerra essa linha. Mover println para dentro do laço interno coloca cada produto em uma linha própria.

Com contagens fixas, multiplique as passagens externas pelas internas. Três passagens externas e quatro passagens internas executam o corpo interno 12 vezes. A tabela acima tem três vezes cinco, ou 15, impressões de produtos.

Permita que o tamanho da linha mude
for (int row = 1; row <= 4; row++) {
    for (int col = 1; col <= row; col++) {
        System.out.print("*");
    }
    System.out.println();
}

O limite interno agora depende da linha. Suas contagens são 1, 2, 3 e 4, portanto o triângulo contém 10 asteriscos. Uma única multiplicação de contagens fixas estaria errada porque o laço interno não é executado o mesmo número de vezes em cada linha.

Use nomes diferentes para contadores de laços cujos escopos se sobrepõem. Declarar outro int i dentro de um laço em que i já está no escopo causa falha de compilação. Para um laço while interno, inicialize seu contador no início de cada passagem externa. Inicializá-lo apenas antes do laço externo o deixa além do limite após a primeira linha.

Rastreie valores em um ponto consistente

Para um laço de 1 a 4, subtraia valores ímpares de um total que começa em 0 e some os pares:

Valor processadoAçãoTotal após a passagem
1Subtrair 1-1
2Somar 21
3Subtrair 3-2
4Somar 42

Registre se uma linha descreve o início ou o fim de uma passagem. Inclua a condição final falsa ao verificar o término. Um rastreamento que misture valores de antes e de depois da atualização pode fazer um laço correto parecer errado.

Coloque separadores entre itens

Cinco números precisam de quatro vírgulas. Imprima um separador antes de cada item, exceto o primeiro:

for (int i = 1; i <= 5; i++) {
    if (i > 1) {
        System.out.print(", ");
    }
    System.out.print(i);
}

A saída é “1, 2, 3, 4, 5”, sem vírgula no início ou no fim. Esse é um problema dos postes de cerca: o número de espaços entre itens é diferente do número de itens.

Teste casos que revelam erros

Experimente zero passagens, uma passagem e os valores em cada limite e próximos a ele. Para laços de entrada, experimente a sentinela primeiro. Para laços aninhados, verifique se a segunda linha reinicia corretamente. Impressões temporárias das variáveis de controle do laço revelam o progresso real. Se um programa travar, examine cada caminho em busca de uma atualização ou saída e interrompa-o com Ctrl+C em um terminal ou com o botão de parada do ambiente de desenvolvimento.

Principais conclusões

  • O laço interno é executado por completo a cada passagem externa.
  • Multiplique as contagens de passagens somente quando ambas forem fixas.
  • Reinicie o contador de um while interno a cada passagem externa.
  • Coloque a quebra de linha de uma linha após seu laço interno.
  • Use um ponto consistente em cada passagem para as linhas da tabela de rastreamento.
  • Teste zero passagens, uma passagem e ambos os lados de um limite.
  • Separadores ficam entre itens, portanto sua quantidade é uma unidade menor.

Exercícios resolvidos de Condições e laços em Java

4 Lições Interativas

1

Transforme uma regra do programa em uma condição

12 passos
Construa comparações, combine-as e verifique seus valores lógicos e sua ordem de avaliação.
  1. 1
    IntroduçãoComece com uma regra sobre os dados

    Uma condição responde a uma pergunta verdadeira ou falsa sobre os dados atuais. Comece com comparações simples e depois combine-as em uma regra que aceite exatamente os valores pretendidos.

    Vamos verificar um intervalo de temperatura, comparar texto e proteger uma divisão inteira. Em cada etapa, distinga o significado da condição da ordem em que Java a avalia.

  2. 2
    ExplicaçãoDê um nome a uma comparação

    Uma comparação produz um boolean, que pode ser armazenado para uso posterior.

    int age = 17;
    boolean isAdult = age >= 18;
    

    Aqui isAdult armazena false. A expressão if (isAdult) testa esse valor diretamente depois. Um inteiro isolado não pode servir como condição: if (age) falha porque Java exige um booleano, não um número tratado como valor lógico.

  3. 3
    ExemploLeia o operador com precisão

    Com a = 7 e b = 10, a < b é verdadeira e a >= b é falsa. As comparações a != b e a == 7 são verdadeiras.

    A diferença entre = e == importa: a atribuição altera uma variável, enquanto a comparação faz uma pergunta. Para um booleano, if (done = true) compila, mas sobrescreve a variável sinalizadora antes de testá-la. Use if (done) para testar o valor existente.

  4. 4
    DicaCompare os caracteres da entrada

    Uma cadeia de caracteres não nula como command tem conteúdo textual e identidade de objeto. command.equals("quit") testa os caracteres; command == "quit" testa a identidade.

    Use equalsIgnoreCase somente quando diferenças entre maiúsculas e minúsculas devam ser aceitas. Por exemplo, “Quit” e “quit” correspondem com esse método, mas são diferentes com equals. Negar uma correspondência exata produz !command.equals("quit").

  5. 5
    ExemploVerifique uma diferença decimal
    double sum = 0.1 + 0.2;
    boolean close = Math.abs(sum - 0.3) < 1e-9;
    

    A soma é armazenada como 0.30000000000000004. A igualdade exata com 0.3 é falsa, mas a diferença absoluta está abaixo dessa tolerância, tornando close verdadeiro. O teste de tolerância aceita uma pequena diferença; ele não altera nenhum dos valores armazenados nem os torna exatamente iguais.

  6. 6
    DesafioTeste um número ímpar negativo

    Um programa usa n % 2 == 1 para detectar inteiros ímpares. O que ele deixa de identificar quando n é -11 e como o teste pode ser corrigido?

    ---reveal---

    -11 % 2 é -1, portanto o teste é falso, embora -11 seja ímpar. Use n % 2 != 0: a divisibilidade por 2 tem resto zero, e restos diferentes de zero, positivos ou negativos, identificam inteiros ímpares.

  7. 7
    ExplicaçãoExija ambos os limites

    Para aceitar temperaturas de 18 a 24 °C, exija ambas as comparações: temp >= 18 && temp <= 24.

    Com 21, ambas são verdadeiras. Com 17, a primeira é falsa; com 25, a segunda é falsa. Usar || entre esses limites internos aceitaria os três valores, pois cada um satisfaz pelo menos um dos dois testes. Cada operando deve ser uma expressão booleana completa.

  8. 8
    Ideia-chaveNegue o intervalo inteiro

    Estar fora do mesmo intervalo significa temp < 18 || temp > 24. Não satisfazer um dos limites é suficiente para estar fora.

    Esta é a lei de De Morgan em ação: !(p && q) equivale a !p || !q. Negar ambas as partes também altera o operador que as une. A outra lei é !(p || q) equivale a !p && !q; manter o operador anterior mudaria quais entradas são aceitas.

  9. 9
    ExemploColoque uma verificação de proteção antes da divisão
    int total = 36;
    int count = 0;
    boolean large = count != 0 && total / count > 10;
    

    A primeira comparação falsa determina o resultado, portanto && ignora a divisão. Isso é avaliação de curto-circuito. Inverter os operandos dividiria por zero antes de verificar count e lançaria uma ArithmeticException. Com ||, um operando esquerdo verdadeiro também faz o direito ser ignorado.

  10. 10
    DesafioDistinga agrupamento de ordem de leitura

    Com a = true, b = false e c = false, a || b && c e (a || b) && c produzem o mesmo resultado? Explique o agrupamento.

    ---reveal---

    Não. A primeira se agrupa como a || (b && c) porque && tem precedência maior, portanto é verdadeira. A segunda exige o resultado de a || b e também c; como c é falso, esse resultado é falso.

  11. 11
    DesafioCombine um limite e uma exceção

    Uma carga é aceita se estiver entre 6 e 14 kg ou se uma liberação especial estiver ativa, mas um cálculo inteiro 100 / count > 5 também deve ser concluído com segurança. Escreva a condição de modo que count igual a 0 não chegue à divisão.

    ---reveal---

    count != 0 && (load >= 6 && load <= 14 || override) && 100 / count > 5

    A primeira verificação de proteção rejeita zero. A escolha agrupada aceita o intervalo ou a liberação especial; apenas um caminho que passe pelas verificações chega à divisão.

  12. 12
    RecapitulaçãoVerifique uma condição dos dois lados

    Antes de usar uma condição, experimente uma entrada que deve ser aceita e outra que deve ser rejeitada. Para intervalos, verifique também os limites.

    Leia os parênteses e a precedência para identificar o agrupamento e depois acompanhe a avaliação de curto-circuito da esquerda para a direita. Isso detecta tanto uma regra de aceitação incorreta quanto um cálculo executado antes de sua verificação de proteção.

2

Escolha um caminho e produza um resultado

14 passos
Acompanhe blocos, ordene casos sobrepostos e use expressões switch para escolhas de valores exatos.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoAcompanhe o caminho que Java alcança
  2. 2
    ExemploExecute exatamente um ramo
  3. 3
    ExplicaçãoMantenha o resultado após a decisão
  4. 4
    DesafioEncontre uma impressão incondicional
  5. 5
    DicaTorne a escolha interna explícita
  6. 6
    ExemploPercorra os limiares na ordem correta
  7. 7
    ConexãoSepare ações independentes
  8. 8
    DesafioCorrija um limite omitido
  9. 9
    ExplicaçãoEscolha por um valor exato
  10. 10
    ExemploAtribua o valor escolhido
  11. 11
    ExplicaçãoForneça seu valor a um bloco
  12. 12
    DesafioAcompanhe a continuação entre casos com dois-pontos
  13. 13
    DesafioEscolha uma estrutura para uma regra mista
  14. 14
    RecapitulaçãoExamine os limites da decisão
3

Acompanhe um laço desde a primeira passagem até a saída

18 passos
Acompanhe laços com teste no início e no final, repetições contadas, passagens puladas e saídas com rótulo.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoObserve a mudança de estado
  2. 2
    ExplicaçãoTeste antes de entrar
  3. 3
    ExemploAcompanhe um produto que muda
  4. 4
    DesafioEvite pular o valor de parada
  5. 5
    ExplicaçãoExecute uma vez antes de decidir
  6. 6
    ExemploLeia uma avaliação antes de testá-la
  7. 7
    DesafioPreveja um limite aceito
  8. 8
    ConexãoLeve a contagem para o cabeçalho
  9. 9
    ExemploConte em passos maiores que uma unidade
  10. 10
    DesafioMantenha o limite pretendido
  11. 11
    DicaVerifique se há um corpo vazio
  12. 12
    ExemploPare na primeira correspondência
  13. 13
    ExplicaçãoPule o restante de uma passagem
  14. 14
    DesafioEncontre a atualização pulada
  15. 15
    ExplicaçãoDê um nome de saída a um laço externo
  16. 16
    ConexãoDistinga saídas de switch e de laço
  17. 17
    DesafioCombine uma passagem pulada e uma saída antecipada
  18. 18
    RecapitulaçãoAcompanhe o próximo destino
4

Construa resultados que descrevam todos os dados processados

19 passos
Combine contadores, valores extremos, variáveis sinalizadoras, algarismos e laços aninhados, verificando seu estado com rastreamentos e casos extremos.

Salve esta aula para seguir cada Lição Interativa passo a passo.

  1. 1
    IntroduçãoDecida o que deve ser mantido entre passagens
  2. 2
    ExplicaçãoSepare uma contagem de uma soma
  3. 3
    ExemploLeia e rejeite a sentinela
  4. 4
    ExemploAcompanhe o estado durante a entrada
  5. 5
    ExplicaçãoPreserve a parte fracionária da média
  6. 6
    DesafioCalcule a média apenas das leituras aceitas
  7. 7
    DicaUse capacidade numérica suficiente desde o início
  8. 8
    ExemploMantenha a melhor leitura
  9. 9
    DesafioRegistre onde ocorre um empate
  10. 10
    Ideia-chaveDeixe uma variável sinalizadora registrar uma correspondência
  11. 11
    ExplicaçãoBusque um divisor
  12. 12
    ExemploExtraia algarismos em uma ordem fixa
  13. 13
    DesafioMantenha o registro de uma leitura negativa
  14. 14
    ExplicaçãoComplete cada linha antes de avançar
  15. 15
    ExemploConte tamanhos de linha que mudam
  16. 16
    DesafioAjuste o separador no primeiro item
  17. 17
    DicaEscolha linhas de rastreamento reveladoras
  18. 18
    DesafioCombine um limite variável com seleção
  19. 19
    RecapitulaçãoVerifique o significado de cada resultado

Questões de Condições e laços em Java

50 Questões de Prática em 5 conjuntos

Conjunto 1: Acompanhe testes, atualizações e saídas de laços10 Questões de Prática

Questão 1 de 10

Quantas vezes o corpo é executado?

int n = 12;
while (n < 8) {
    n++;
}
  1. 1 vez
  2. 4 vezes
  3. 0 vezes
  4. 5 vezes
Mostrar respostaOcultar resposta
Resposta: C
Um laço while verifica sua condição antes de entrar no corpo. A comparação inicial 12 < 8 é falsa, portanto não há incremento nem execução do corpo. Uma primeira passagem obrigatória pertence ao do-while, cujo teste vem depois do corpo.

Questão 2 de 10

O que é impresso?

int level = 9;
do {
    level -= 2;
} while (level > 8);
System.out.println(level);
  1. 7
  2. 9
  3. 8
  4. 5
Mostrar respostaOcultar resposta
Resposta: A
O corpo do do-while é executado primeiro e subtrai 2, alterando level para 7. Sua condição é então falsa, portanto o laço termina. Manter 9 trataria isso como um laço while com teste no início e pularia a primeira execução do corpo.

Questão 3 de 10

Quantas execuções do corpo ocorrem?

for (int k = 2; k <= 17; k += 4) {
    System.out.println(k);
}
  1. 3
  2. 5
  3. 6
  4. 4
Mostrar respostaOcultar resposta
Resposta: D
O corpo usa 2, 6, 10 e 14. A atualização seguinte produz 18, que falha no teste do limite superior inclusivo. Incluir 17 apenas porque a condição usa <= seria um erro: o passo nunca alcança esse valor.

Questão 4 de 10

O que é impresso, ignorando o espaço final?

for (int k = 2; k <= 7; k++) {
    if (k % 2 == 0) {
        continue;
    }
    System.out.print(k + " ");
}
  1. “2 4 6”
  2. “3 5 7”
  3. “3”
  4. “3 4 5 6 7”
Mostrar respostaOcultar resposta
Resposta: B
Valores pares passam por continue e pulam a impressão; valores ímpares a alcançam. A atualização do laço for ainda é executada após continue, portanto o contador continua avançando. Imprimir apenas 3 confundiria pular uma passagem com encerrar todo o laço.

Questão 5 de 10

Quais são os valores de amount e steps após este laço?

int amount = 3;
int steps = 0;
while (amount < 40) {
    amount *= 2;
    steps++;
}
  1. amount = 24, steps = 3
  2. amount = 40, steps = 4
  3. amount = 48, steps = 5
  4. amount = 48, steps = 4
Mostrar respostaOcultar resposta
Resposta: D
A quantidade passa por 6, 12, 24 e 48, com um passo registrado por duplicação. O teste falha somente após chegar a 48. Parar em 24 confunde o último valor que satisfaz a condição com o valor que permanece após a última execução do corpo.

Questão 6 de 10

Qual é o valor final de total?

int total = 0;
for (int k = 1; k <= 8; k++) {
    if (k % 3 == 0) {
        continue;
    }
    total += k;
    if (total > 12) {
        break;
    }
}
  1. 12
  2. 13
  3. 19
  4. 15
Mostrar respostaOcultar resposta
Resposta: C
As adições são 1, 2, 4, 5 e 7 porque 3 e 6 são pulados. Elas deixam os totais 1, 3, 7, 12 e 19; a última adição aciona break. Terminar em 12 significaria ler incorretamente > como >= ou verificar o limite antes de somar.

Questão 7 de 10

Um laço do-while lê um inteiro de 2 a 6. Qual condição faz o laço se repetir exatamente enquanto o valor for inválido?
  1. value < 2 || value > 6
  2. value >= 2 && value <= 6
  3. value < 2 && value > 6
  4. value <= 2 || value >= 6
Mostrar respostaOcultar resposta
Resposta: A
Valores inválidos estão abaixo de 2 ou acima de 6, portanto qualquer um dos limites externos deve acionar outra passagem. Usar <= e >= rejeitaria os limites permitidos. Unir os dois testes externos com && nunca provocaria repetição porque nenhum inteiro satisfaz ambos.

Questão 8 de 10

Um cabeçalho for declara int index. Onde o código pode ler essa variável?
  1. Em qualquer ponto do método main.
  2. Apenas na atualização do cabeçalho.
  3. Apenas após o término do laço.
  4. Apenas dentro desse laço for.
Mostrar respostaOcultar resposta
Resposta: D
Uma variável declarada em um cabeçalho for está no escopo do cabeçalho e do corpo do laço, mas seu escopo termina com o laço. Lê-la depois causa falha de compilação. Para manter o valor final do contador, declare a variável antes da instrução for.

Questão 9 de 10

O que é impresso?

int hits = 0;
outer:
for (int row = 1; row <= 4; row++) {
    for (int col = 1; col <= 4; col++) {
        if (row + col == 5) {
            break outer;
        }
        hits++;
    }
}
System.out.println(hits);
  1. 6
  2. 3
  3. 9
  4. 12
Mostrar respostaOcultar resposta
Resposta: B
Na linha 1, as colunas 1, 2 e 3 incrementam hits. A coluna 4 faz a soma ser 5, e o break com rótulo sai do laço externo antes de outro incremento. Contar as linhas posteriores trataria o break com rótulo como um break comum que encerra apenas o laço interno.

Questão 10 de 10

Por que este laço nunca termina?

int n = 1;
while (n != 12) {
    n += 2;
}
  1. A atualização diminui n a cada passagem.
  2. A condição é verificada apenas uma vez.
  3. A sequência permanece ímpar e pula 12.
  4. O corpo redefine n como 1 a cada passagem.
Mostrar respostaOcultar resposta
Resposta: C
Começar em 1 e somar 2 repetidamente produz apenas números ímpares, portanto n nunca se torna 12. A desigualdade permanece verdadeira mesmo depois que n ultrapassa o limite pretendido. Um limite como n < 12 detectaria a ultrapassagem em vez de exigir que o valor exato fosse alcançado.
Conjunto 2: Leia condições e escolha um caminho10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Por que este código não compila?

int value = 8;
String label;
if (value > 5) {
    label = "large";
}
System.out.println(label);
  1. label está fora de seu escopo declarado.
  2. Um if não pode atribuir um valor de texto.
  3. label não recebe valor em todos os caminhos.
  4. A comparação deve usar >= em seu lugar.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Qual valor é armazenado em mode?

String command = "RUN";
int mode = switch (command) {
    case "run" -> 1;
    case "wait" -> 2;
    default -> 3;
};
  1. 1
  2. 2
  3. 0
  4. 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Com int sum = 15; e int count = 0;, o que acontece ao avaliar count == 0 || sum / count > 4?
  1. O resultado é false sem divisão.
  2. O resultado é true sem divisão.
  3. Uma ArithmeticException é lançada.
  4. O resultado é true após a divisão.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Um programa permite a entrada quando member && !blocked || guest && codeValid é verdadeiro. Qual condição rejeita exatamente as entradas que ele permitiria?
  1. (!member || blocked) && (!guest || !codeValid)
  2. (!member && blocked) || (!guest && !codeValid)
  3. (!member || blocked) || (!guest || !codeValid)
  4. (!member && blocked) && (!guest && !codeValid)
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Qual é o valor de -13 % 2 != 0?
  1. false
  2. true
  3. -1
  4. 1
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Uma String command não nula contém texto lido da entrada. Qual expressão testa se seu conteúdo é exatamente “pause”?
  1. command == "pause"
  2. command.equalsIgnoreCase("pause")
  3. !command.equals("pause")
  4. command.equals("pause")
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Qual condição aceita uma massa de 4 a 9 kg, incluindo ambos os limites?
  1. mass >= 4 && mass <= 9
  2. mass > 4 && mass < 9
  3. mass >= 4 || mass <= 9
  4. mass < 4 || mass > 9
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

O que isto imprime?

boolean ready = true;
boolean locked = false;
boolean expired = false;
System.out.println(ready || locked && expired);
  1. false
  2. true false
  3. true
  4. false false
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

O que este código imprime?

int stock = 0;
if (stock > 0) {
    System.out.print("available ");
} else {
    System.out.print("empty ");
}
System.out.print("checked");
  1. “available checked”
  2. “empty checked”
  3. “empty”
  4. “available empty checked”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

O que é impresso?

int load = 74;
if (load >= 50) {
    System.out.print("medium");
} else if (load >= 70) {
    System.out.print("high");
} else {
    System.out.print("low");
}
  1. “medium”
  2. “high”
  3. “mediumhigh”
  4. “low”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 3: Calcule resultados ao longo de entradas repetidas10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Qual valor inicial um acumulador deve usar antes de multiplicar os inteiros de 2 a 6?
  1. 0
  2. 2
  3. 6
  4. 1
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Um laço lê 9, 4, 8 e depois a sentinela -1. Ele verifica a sentinela antes de atualizar a soma e a contagem. Qual média deve informar?
  1. 5.0
  2. 7.0
  3. 5.25
  4. 6.666666666666667
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Com int sum = 17; e int count = 4;, qual é o resultado de (double) (sum / count)?
  1. 4.25
  2. 4.5
  3. 4.0
  4. 5.0
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Um laço que encontra a leitura máxima processará apenas inteiros negativos. Por que inicializar max em 0 pode produzir a resposta errada?
  1. Nenhuma entrada negativa pode substituir esse valor inicial.
  2. Toda entrada negativa substituirá esse valor inicial.
  3. O zero impede que o laço de entrada comece.
  4. A comparação de inteiros negativos causa estouro.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

O que é impresso?

int n = 6205;
int sum = 0;
while (n > 0) {
    sum += n % 10;
    n /= 10;
}
System.out.println(sum);
  1. 12
  2. 56
  3. 13
  4. 5026
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Quantos asteriscos são impressos no total?

for (int row = 2; row <= 5; row++) {
    for (int col = 1; col < row; col++) {
        if (col == 2) {
            continue;
        }
        System.out.print("*");
    }
}
  1. 6
  2. 9
  3. 10
  4. 7
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Quais são os valores de best e position depois?

int best = Integer.MIN_VALUE;
int position = 0;
for (int day = 1; day <= 5; day++) {
    int value = day % 3 - 4;
    if (value >= best) {
        best = value;
        position = day;
    }
}
  1. best = -2, position = 2
  2. best = -2, position = 5
  3. best = -3, position = 4
  4. best = -4, position = 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Um laço contou 7 leituras aceitas de um total de 12 leituras. Qual expressão calcula a porcentagem aceita com um resultado fracionário?
  1. 100.0 * accepted / total
  2. accepted / total * 100.0
  3. (double) (accepted / total) * 100
  4. (double) (100 * (accepted / total))
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Qual é a saída?

for (int k = 3; k <= 5; k++) {
    if (k > 3) {
        System.out.print(", ");
    }
    System.out.print(k);
}
  1. “, 3, 4, 5”
  2. “3, 4, 5, ”
  3. “3, 4, 5”
  4. “345”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

O que este código imprime?

boolean allPositive = true;
for (int k = 1; k <= 4; k++) {
    int value = k - 2;
    if (value <= 0) {
        allPositive = false;
    } else {
        allPositive = true;
    }
}
System.out.println(allPositive);
  1. false, porque um valor anterior não era positivo.
  2. true, embora nem todos os valores fossem positivos.
  3. true, porque todos os valores gerados eram positivos.
  4. false, embora todos os valores gerados fossem positivos.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 4: Combine decisões com padrões de laços10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Qual palavra-chave fornece um resultado a partir de um caso com bloco de várias instruções em uma expressão switch?
  1. yield
  2. break
  3. continue
  4. default
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

O que é impresso?

int result = 0;
switch (2) {
    case 1:
        result += 2;
    case 2:
        result += 3;
    case 3:
        result += 5;
        break;
    default:
        result = -1;
}
System.out.println(result);
  1. 3
  2. 10
  3. 8
  4. -1
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Qual é o valor de total após o laço?

int total = 0;
for (int k = 1; k <= 5; k++) {
    switch (k % 3) {
        case 0:
            break;
        default:
            total += k;
    }
    total++;
}
  1. 14
  2. 17
  3. 16
  4. 5
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

Qual é o total final?

int total = 0;
for (int n = 1; n <= 9; n++) {
    if (n % 2 == 0) {
        total += 2;
    } else if (n % 3 == 0) {
        total += 3;
    } else {
        total--;
    }
}
  1. 14
  2. 8
  3. 9
  4. 11
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Um laço de validação aceita inteiros de 10 a 14. Ele lê as entradas 8, 14 e depois 11 com do { ... } while (value < 10 || value > 14);. Quantas entradas ele consome?
  1. 1
  2. 3
  3. 2
  4. 4
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

O que é impresso?

int n = 58;
int result = 0;
do {
    int digit = n % 10;
    if (digit % 2 == 0) {
        result = result * 10 + digit;
    }
    n /= 10;
} while (n > 0);
System.out.println(result);
  1. 8
  2. 85
  3. 5
  4. 58
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Um laço aninhado imprime quatro linhas de seis valores. A chamada de quebra de linha está após o laço interno, mas dentro do laço externo. Quantas impressões de valores e chamadas de quebra de linha são executadas?
  1. 24 impressões de valores e 24 chamadas de quebra de linha.
  2. 10 impressões de valores e 4 chamadas de quebra de linha.
  3. 24 impressões de valores e 6 chamadas de quebra de linha.
  4. 24 impressões de valores e 4 chamadas de quebra de linha.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Por que Math.abs((0.1 + 0.2) - 0.3) < 1e-9 pode ser verdadeiro enquanto (0.1 + 0.2) == 0.3 é falso?
  1. A tolerância muda a soma armazenada para exatamente 0,3.
  2. A diferença calculada é diferente de zero, mas está abaixo da tolerância.
  3. O operador de igualdade compara identidades de objetos double.
  4. A chamada de valor absoluto arredonda toda diferença para zero.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um laço com sentinela deve calcular a média de inteiros positivos até 0. Seu corpo lê um valor, incrementa count, verifica se é 0 e usa break, depois soma o valor. Para as entradas 6, 10, 0, ele imprime (double) sum / count. Qual é o resultado e qual correção é necessária?
  1. Cerca de 5,3333; conte apenas após o teste de parada.
  2. 8,0; mova a atualização da soma para antes do teste de parada.
  3. 16,0; inicialize count em 1 antes da leitura.
  4. Cerca de 5,3333; converta o quociente já calculado.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

O que este código imprime?

for (int n = 4; n > 0; n--);
{
    System.out.print("done");
}
  1. “done” quatro vezes
  2. Nada
  3. “done” indefinidamente
  4. “done” uma vez
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Conjunto 5: Encontre erros e preveja comportamentos combinados10 Questões de Prática

Salve esta aula para ver todas as respostas e praticar cada conjunto.

Questão 1 de 10

Uma busca imprime o primeiro inteiro de 25 a 75 que é divisível por 4 ou por 7, mas não por ambos. O que ela imprime?
  1. 28
  2. 35
  3. 32
  4. 36
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 2 de 10

Uma cadeia rejeita score < 0 || score > 40, depois classifica score >= 30 como “high”, score >= 18 como “middle” e o restante como “low”. Quais classificações as pontuações 40, 41 e 18 recebem, nessa ordem?
  1. “invalid”, “invalid”, “low”
  2. “high”, “invalid”, “middle”
  3. “high”, “high”, “middle”
  4. “high”, “invalid”, “low”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 3 de 10

Qual é o valor de !(false || true)?
  1. true
  2. 0
  3. false
  4. 1
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 4 de 10

O que é impresso?

int a = -2;
int b = 5;
if (a > 0)
    if (b > 0)
        System.out.print("both");
    else
        System.out.print("one");
System.out.print("end");
  1. “oneend”
  2. “end”
  3. “bothend”
  4. “bothoneend”
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 5 de 10

Qual valor é atribuído?

int level = 3;
int result = switch (level) {
    case 1, 2 -> 4;
    case 3 -> {
        int base = level * 2;
        yield base + 1;
    }
    default -> 0;
};
  1. 6
  2. 4
  3. 0
  4. 7
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 6 de 10

Qual é o count final?

int count = 0;
outer:
for (int row = 1; row <= 3; row++) {
    for (int col = 1; col <= 3; col++) {
        if (row == col) {
            continue outer;
        }
        count++;
    }
}
  1. 3
  2. 6
  3. 0
  4. 9
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 7 de 10

Para n = 143, um laço que verifica se um número é primo começa no divisor 2 e continua enquanto d * d <= n, usando break quando o resto é zero. Em qual divisor ele usa break pela primeira vez?
  1. 7
  2. 11
  3. 12
  4. 13
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 8 de 10

Qual é o valor de count ao final?

int count = 0;
int col = 1;
for (int row = 1; row <= 3; row++) {
    while (col <= row) {
        count++;
        col++;
    }
}
  1. 6
  2. 1
  3. 9
  4. 3
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 9 de 10

Um laço de entrada para na sentinela -9 e deve calcular a média apenas dos valores positivos. Inicializando sum e count em 0, ele verifica a sentinela, depois soma cada valor de dados a sum, mas incrementa count apenas para os positivos. Para as entradas -4, 6, -2, 10, -9, o que (double) sum / count imprime e qual correção é necessária?
  1. 5.0; some e conte apenas valores positivos.
  2. 8.0; some e conte apenas valores positivos.
  3. 2.5; some e conte todos os valores de dados.
  4. 5.0; some os positivos, mas conte todos os valores de dados.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Questão 10 de 10

Qual contagem de algarismos isto produz para n = 0?

int n = 0;
int digits = 0;
do {
    digits++;
    n /= 10;
} while (n > 0);
  1. 0
  2. 10
  3. 1
  4. Nunca para.
Mostrar respostaOcultar resposta

Salve esta aula para ver esta resposta.

Travou em uma questão sua? Ajuda com Tarefas

Termos-Chave

63 Termos-Chave, cada um com sua definição

A

Acumulador
Um acumulador armazena um resultado acumulado ao longo das passagens de um laço, somando ou multiplicando cada valor aceito ao resultado anterior.
Um acumulador inicializado antes do laço mantém a distância total percorrida ao longo de vários dias.
Atualização
Uma atualização altera o estado de controle do laço após a conclusão normal do corpo; um cabeçalho for coloca essa operação após sua condição.
A atualização i += 4 move o contador de 2 para 6 depois que a primeira execução do corpo do laço for termina.
Avaliação de curto-circuito
A avaliação de curto-circuito ignora o operando direito de && ou || quando o operando esquerdo já determina todo o resultado.
A avaliação de curto-circuito torna count != 0 && sum / count > 5 segura quando ambas as variáveis são ints.

B

Bloco
Um bloco agrupa instruções entre chaves para que um ramo ou laço possa tratar o grupo como seu corpo, com seu próprio escopo de variáveis locais.
Um bloco ao redor de duas instruções de impressão torna ambas condicionais ao mesmo teste if.
Busca
Uma busca examina candidatos até encontrar uma correspondência exigida ou esgotar os candidatos disponíveis sem encontrar uma.
Uma busca pode parar no primeiro número cujo quadrado ultrapassa o limite escolhido.

C

Cadeia de else-if
Uma cadeia de else-if testa várias condições em ordem e executa apenas o primeiro ramo verdadeiro, ou seu else final quando nenhum teste é satisfeito.
Uma cadeia de else-if atribui uma nota mesmo quando a pontuação satisfaz vários limiares inferiores.
Caso extremo
Um caso extremo é uma entrada ou estado inicial próximo de um limite, como dados vazios, uma passagem ou um valor-limite, que pode revelar um erro oculto.
Um caso extremo em que a sentinela é inserida primeiro verifica se um laço que calcula médias trata a ausência de dados.
Condição de continuação
Uma condição de continuação descreve quando outra passagem do laço deve ocorrer; um resultado verdadeiro repete e um resultado falso encerra a repetição.
A condição de continuação para a entrada de uma avaliação é verdadeira fora do intervalo de 1 a 5.
Contador
Um contador registra quantos eventos ou valores que atendem a uma condição ocorreram, geralmente começando em zero e aumentando uma vez por correspondência.
Um contador aumenta apenas para leituras aceitas, mantendo correto o denominador de sua média.
Continuação entre casos
A continuação entre casos é a execução que passa de um caso com dois-pontos para as instruções de casos posteriores até uma saída ou o fim do switch.
Um break ausente causa uma continuação entre casos, de modo que a correspondência com o primeiro caso imprime a sua mensagem de status e, em seguida, também a mensagem do caso seguinte.
Contraexemplo
Um contraexemplo é um valor que torna falsa uma afirmação sobre todos os valores; uma variável sinalizadora de correspondência de todos permanece falsa após encontrá-lo.
Uma leitura zero é um contraexemplo à afirmação de que todo valor registrado é positivo.

D

Divisão inteira
A divisão inteira divide operandos inteiros e descarta qualquer parte fracionária, portanto converter seu resultado já calculado não pode recuperar essa parte.
A divisão inteira produz 4 para 17 / 4, motivo pelo qual um cálculo de média converte primeiro um operando.

E

E lógico
O E lógico une duas expressões booleanas e é verdadeiro somente quando ambas são verdadeiras; Java escreve sua forma com curto-circuito como &&.
Um E lógico une os limites inferior e superior quando ambos devem ser satisfeitos para uma temperatura aceita.
Else pendente
Um else pendente é um else cujo agrupamento visual pode não ser claro; Java o associa ao if anterior mais próximo ainda sem correspondência.
As chaves resolvem o else pendente quando uma verificação externa de ingresso contém uma verificação interna de idade.
Erro de uma unidade
Um erro de uma unidade faz um laço ser executado uma vez a mais ou a menos, geralmente porque seu valor inicial ou teste do limite final está errado.
Um erro de uma unidade omite o valor final quando um laço usa < 12, mas deve incluir 12.
Escopo
O escopo de uma variável local é a parte do programa em que essa variável pode ser nomeada; o escopo de uma declaração em um bloco termina na chave de fechamento.
O escopo de um resultado declarado antes de um if permite que a impressão seguinte leia o valor atribuído.
Estouro
O estouro ocorre quando um resultado inteiro excede o intervalo de seu tipo e retorna a um valor diferente sem informar um erro aritmético.
O estouro em um acumulador int compromete uma soma grande, embora cada entrada individual caiba em um int.
Exaustividade
A exaustividade significa que um switch que produz valor considera todos os valores possíveis do seletor, de modo que nenhuma entrada fique sem resultado.
Um caso default fornece exaustividade para um switch de int com apenas alguns rótulos explícitos.
Expressão switch
Uma expressão switch escolhe e produz um valor a partir dos casos correspondentes, de modo que seu resultado possa ser atribuído ou usado em outra expressão.
Uma expressão switch atribui o número de dias selecionando o caso do mês atual.
Extração de algarismos
A extração de algarismos obtém o último algarismo decimal de um inteiro não negativo com % 10, para uso antes que a divisão o remova.
A extração de algarismos percorre os algarismos da direita para a esquerda quando um laço divide repetidamente por 10.

I

Inicialização
A inicialização dá a uma variável seu valor inicial; a inicialização de um laço for é executada uma vez antes de seu primeiro teste de condição.
A inicialização define uma contagem regressiva em 8 antes que o cabeçalho comece a testá-la e diminuí-la.
Instrução break
Uma instrução break sai imediatamente da estrutura à qual se aplica; sem rótulo, essa estrutura é o laço ou switch mais próximo que a contém.
Uma instrução break interrompe a busca quando o primeiro candidato que satisfaz os testes exigidos é encontrado.
Instrução break com rótulo
Uma instrução break com rótulo nomeia uma instrução com rótulo que a contém como destino da saída, permitindo que uma busca aninhada saia de um laço externo.
Uma instrução break com rótulo encerra imediatamente os dois laços de busca quando o par exigido é encontrado.
Instrução continue
Uma instrução continue pula o restante do corpo atual do laço e segue para sua próxima passagem, incluindo a atualização de um laço for básico.
Uma instrução continue pula a impressão de um valor indesejado, mas ainda permite que o contador do for avance.
Instrução continue com rótulo
Uma instrução continue com rótulo se aplica a um laço com rótulo que a contém, abandonando o trabalho atual e seguindo para a próxima passagem desse laço.
Uma instrução continue com rótulo segue para a atualização do for externo em vez de verificar as colunas restantes.
Instrução yield
A instrução yield fornece um valor a partir de um caso com bloco de uma expressão switch, após quaisquer cálculos anteriores nesse bloco.
Uma instrução yield fornece 29 após um caso de fevereiro determinar que o ano é bissexto.
Iteração
Uma iteração é uma execução do corpo de um laço; a condição do laço determina se outra passagem pode começar ou se a repetição termina.
Uma iteração dobra a quantidade armazenada e aumenta em um o número de dias decorridos.

L

Laço aninhado
Um laço aninhado é um laço colocado dentro de outro, de modo que sua repetição completa seja alcançada a cada passagem do corpo que o contém.
Um laço aninhado imprime todas as colunas de uma linha antes que o laço externo avance para a próxima.
Laço com teste no final
Um laço com teste no final verifica se haverá outra passagem após a execução de seu corpo; a forma do-while de Java coloca a condição depois da chave de fechamento.
Um laço com teste no final pode exibir um menu uma vez mesmo quando o primeiro comando o encerra imediatamente.
Laço do-while
Um laço do-while executa seu corpo antes de testar sua condição, portanto pelo menos uma passagem ocorre antes que ele possa parar de se repetir.
Um laço do-while pede uma avaliação antes de verificar se outra tentativa é necessária.
Laço externo
Um laço externo contém outro laço e controla quantas vezes a repetição interna começa, normalmente avançando uma linha por passagem.
O laço externo é executado quatro vezes quando uma tabela precisa de quatro linhas com uma quebra de linha após cada uma.
Laço for
Um laço for reúne inicialização, teste repetido de condição e atualização em um cabeçalho, tornando fácil acompanhar uma repetição contada.
Um laço for percorre os inteiros de 1 a 12 e soma cada valor a uma soma acumulada.
Laço infinito
Um laço infinito continua se repetindo sem uma saída, muitas vezes porque uma atualização necessária está ausente ou um valor de parada nunca é alcançado.
Um contador que permanece em 1 enquanto testa i <= 5 produz um laço infinito, a menos que outro caminho saia dele.
Laço interno
Um laço interno é contido por outro laço e executa uma tarefa repetida, como visitar cada coluna da linha atual.
O laço interno começa novamente na coluna 1 em cada linha quando seu contador é reiniciado corretamente.
Laço while
Um laço while testa uma condição booleana antes de cada execução do corpo e pode realizar zero passagens quando seu primeiro teste é falso.
Um laço while continua dobrando uma quantidade até que ela alcance ou ultrapasse sua meta.
Leis de De Morgan
As leis de De Morgan negam um teste booleano combinado negando ambos os operandos e trocando o operador que os une entre E e OU.
As leis de De Morgan transformam um teste para não estar dentro de um intervalo fechado em um OU de dois limites externos.
Limiar
Um limiar é um valor de corte que separa resultados; seu operador de comparação determina se o próprio valor de corte pertence a um caso.
Um limiar escrito como score >= 30 inclui 30, enquanto score > 30 deixa essa pontuação exata de fora.

M

Máximo
Um máximo é o maior valor nos dados processados; um laço o mantém substituindo o melhor valor armazenado apenas quando apropriado.
O máximo de várias temperaturas negativas deve começar a partir dos dados ou de um valor inicial suficientemente baixo.
Mínimo
Um mínimo é o menor valor nos dados processados, acompanhado pela substituição do melhor valor armazenado quando aparece uma leitura menor.
O mínimo permanece inalterado em um dia mais quente porque a nova leitura não é menor.

N

Negação
A negação inverte um valor booleano com !, transformando verdadeiro em falso e falso em verdadeiro sem alterar os dados subjacentes.
A negação em !command.equals("stop") é verdadeira enquanto o texto inserido for diferente de “stop”.
Número primo
Um número primo é um inteiro de pelo menos 2 que não tem divisores positivos além de 1 e dele mesmo; encontrar outro divisor o descarta.
O teste de número primo rejeita 91 quando chega ao divisor 7, porque o resto é zero.

O

Operador condicional
O operador condicional ?: seleciona um de dois valores de expressão a partir de uma condição booleana, permitindo uma escolha curta entre dois valores.
O operador condicional define label como “even” ou “odd” de acordo com um teste de resto.
Operador de atribuição
O operador de atribuição = armazena um valor em uma variável; a expressão resultante tem esse valor atribuído, não um resultado de comparação.
Usar o operador de atribuição em if (done = true) altera a variável sinalizadora antes da execução do ramo.
Operador de igualdade
O operador de igualdade == compara valores primitivos, mas, em referências a objetos como cadeias de caracteres, testa se os objetos são idênticos.
O operador de igualdade aceita 3 == 3.0 porque a conversão numérica torna seus valores iguais.
Operador relacional
Um operador relacional testa a relação entre dois valores e produz um booleano, como ao verificar se um número é maior que outro.
O operador relacional <= inclui uma pontuação igual ao limite superior de um intervalo permitido.
OU exclusivo
O OU exclusivo é verdadeiro quando exatamente um de dois operandos booleanos é verdadeiro; Java expressa essa operação com o operador ^.
O OU exclusivo rejeita um valor divisível por ambos os números testados quando exatamente uma regra de divisibilidade deve ser satisfeita.
OU lógico
O OU lógico une duas expressões booleanas e é verdadeiro quando pelo menos uma é verdadeira, inclusive quando ambas são; sua forma com curto-circuito é ||.
Um OU lógico aceita um comando quando ele corresponde a qualquer um de dois rótulos de texto permitidos.

P

Precedência de operadores
A precedência de operadores determina como as expressões são agrupadas sem parênteses; o E lógico é agrupado antes do OU lógico.
A precedência de operadores faz a || b && c significar a || (b && c), embora o OU apareça primeiro.
Problema dos postes de cerca
Um problema dos postes de cerca surge quando itens e espaços entre eles têm quantidades diferentes, como cinco valores impressos que precisam de quatro separadores.
Um problema dos postes de cerca é evitado imprimindo uma vírgula antes de cada número, exceto o primeiro.

R

Ramo
Um ramo é um caminho por uma decisão; uma instrução if-else seleciona um de seus dois ramos de acordo com uma condição booleana.
O ramo falso imprime “Try again” quando a avaliação inserida não atende à condição exigida.
Resto
Um resto é o valor deixado por % após uma divisão inteira; um resto zero identifica um valor divisível pelo divisor.
O resto em -13 % 2 é -1, portanto testar se o resto é diferente de zero reconhece esse inteiro ímpar.
Rótulo de case
Um rótulo de case nomeia um valor fixo aceito por um caso de switch; vários rótulos separados por vírgulas podem compartilhar uma ação com seta.
Um rótulo de case para 6 pode compartilhar uma ação de fim de semana com o rótulo para 7 em um switch com seta.

S

Saída antecipada
Uma saída antecipada encerra um laço antes que sua condição normalmente o interrompa, muitas vezes porque um resultado de busca ou comando de parada foi encontrado.
Uma saída antecipada impede que uma sentinela de entrada seja acrescentada a uma soma acumulada ou contada como dado.
Seletor
Um seletor é o valor avaliado por um switch e comparado com seus rótulos de case para escolher qual código ou expressão será executado.
O seletor command envia o texto “wait” para um caso com esse rótulo exato de cadeia de caracteres.
Sentinela
Uma sentinela é um valor de entrada designado que sinaliza o fim de uma sequência e é verificado antes do processamento comum dos dados.
Uma sentinela de -1 encerra a leitura sem se tornar um item extra na contagem ou na soma dos dados.
Soma acumulada
Uma soma acumulada é a soma de todos os valores processados até o momento, atualizada a cada passagem e disponível para uma apresentação intermediária ou final.
Uma soma acumulada impressa após cada adição mostra o progresso antes da inserção da última entrada.

T

Tabela de rastreamento
Uma tabela de rastreamento registra valores selecionados do programa em pontos consistentes durante a execução, tornando visíveis as mudanças de estado e os caminhos do laço.
Uma tabela de rastreamento mostra o total após cada passagem e a condição que finalmente interrompe o laço.
Teste de valor-limite
Um teste de valor-limite verifica um valor em um ponto de corte ou próximo a ele, ajudando a revelar lacunas, sobreposições e limites incluídos ou excluídos incorretamente.
Um teste de valor-limite usando 29, 30 e 31 verifica a transição para uma categoria que começa em 30.
Tolerância
Uma tolerância é um tamanho de diferença permitido, usado ao comparar números calculados que podem conter pequenos erros de arredondamento.
Uma tolerância de 1e-9 aceita a pequena diferença entre 0.1 + 0.2 e 0.3 neste cálculo.

V

Validação de entrada
A validação de entrada verifica se um valor inserido atende às condições permitidas pelo programa antes de esse valor ser classificado ou processado.
A validação de entrada rejeita uma pontuação acima de 100 antes que uma cadeia de notas possa classificá-la como “A”.
Valor booleano
Um valor booleano é true ou false; comparações produzem esse valor, e condições em Java exigem uma expressão desse tipo.
O valor booleano armazenado em isFull se torna verdadeiro quando um recipiente atinge sua capacidade.
Variável de controle do laço
Uma variável de controle do laço mantém um estado variável usado para controlar ou descrever a repetição, como a contagem atual ou um valor candidato.
A variável de controle do laço avança de três em três, portanto uma verificação de limite pode parar mesmo quando uma meta exata é pulada.
Variável sinalizadora
Uma variável sinalizadora é uma variável booleana que registra se uma condição foi satisfeita, como uma correspondência encontrada ou um contraexemplo identificado.
Uma variável sinalizadora para alguma leitura negativa permanece verdadeira após uma correspondência, mesmo que a última leitura seja positiva.

Sobre esta aula

Por StudeliRelatar um erro

Crie seus próprios Materiais de Estudo

Transforme suas anotações, slides e documentos em Guias de Estudo, Questões de Prática, Flashcards e mais 6 ferramentas.

Começar