sexta-feira, 6 de fevereiro de 2015

0.0.0.8 - Comandos de Seleção

Gramática do Java e programação 3

Objetivo desta aula:

Apresentar os comandos de seleção.

links citados durante a aula

Especificação da linguagem Java

Tutorial sobre if else em Java

Tutorial sobre switch em Java

Introdução

A sequência padrão de execução de comandos em um método (como main) é linear e "de cima para baixo". Podemos modificar isso usando certos comandos. Os primeiros que estudaremos são if e switch.

A sintaxe mais simples do comando if é:

   if <expr> {
    // bloco de código a executar caso <expr> seja verdadeiro  
   }
  

Quando inserimos essa sequência de comando, executamos o bloco de código caso a expressão seja verdadeira, ou conversametne, "saltamos" a execução do bloco de código que sucede a expressão caso esta resulte falsa. Geralmente <expr> é uma expressão relacional. Pode também ser uma variável booleana. Em casos raros (como em exemplos e depuração de código) são literais, caso em que o compilador apresenta um aviso (warning).

Incluindo os comandos antes e depois do teste, teremos algo semelhante ao apresentado abaixo. Nesse código, comandos são executados antes do teste, faz-se o teste, se resultar verdadeiro então executa o bloco. Qualquer que seja o resultado, executa os comandos depois do teste.

   // comandos executados antes do teste
   if <expr> {
    // bloco de código a executar caso <expr> seja verdadeiro  
   }
   // comandos executados depois do teste
  

Exemplo : Digite e teste

   class Selecao {
    // comandos executados antes do teste
    public static void main (String[] args) {
     System.out.println ("Iniciando");
     int idade = 44;  // teste para várias idades
     if (idade>65) {
      // bloco de código a executar caso <expr> seja verdadeiro
      System.out.println ("É idoso");  
     }
     // comandos executados depois do teste
     System.out.println ("Encerrando.")
    }
   }
  

Faça o mesmo para todos os exemplos na seção sobre lógica.

Outra sintaxe:

   if <expr> {
    // A : bloco de código a executar caso <expr> seja verdadeiro  
   } else {
    // B : bloco de código a executar caso <expr> seja falso  
   }
  

Quando inserimos essa sequência de comando, executamos ou o bloco A ou o bloco B, dependendo de <expr> . Se for verdadeira, executamos apenas A, se for falsa, executamos apenas B. Nunca acontece de executar ambos ou nenhum.

   class LeaoDeChacara {
    public static void main (String[] args) {
     System.out.println ("Checagem de maioridade, RG por favor!");
     if (idade <18) {
      System.out.println ("Apenas maiores podem entrar!!");
     } else {
      System.out.println ("Pode entrar, bom divertimento!");
     }
    }
   }
  

Proposta: modifique o código acima para que ele funcione da mesma maneira trocando a posição dos blocos A e B.

Podemos colocar novos blocos de if dentro dos blocos A e B. Isto é muito comum. Veja no exemplo abaixo, adaptado daqui.

Para dar o desconto na compra de um televisor, caso a tela seja de LCD, o desconto é de 10%. Caso seja LED, se a tela tiver menos que 40 polegadas o desconto é de 8%, se tiver 40 ou mais polegadas o desconto é de 5%.

   class DescontaTV {
    public static void main (String[] args) {
     char LED='E', LCD='C';
     char tipo;
     int tamanho=0;
     int desconto=0;
    
     tipo=LED;
     tamanho=42;
     if(tipo == LCD)
    
     {
      desconto=10;
     }
     else
     {
      if(tipo == LED)
      {
       if(tamanho<40)
       {
        desconto=8;
       }
       else
       {
        desconto=5;
       }
      }
     }
    }
   }
  

Quando aninhamos muitos blocos de if, se quisermos colocar um bloco else, em princípio não saberemos a que if esse else pertence. Esse é o dangling else problem ou problema do else pendurado. Em Java, esse else pertence ao if mais interno.

Exemplo: Como este fragmento de código será executado??

  // fragmento A
  if ( num > 0 )   
    if ( num < 10 ) 
      System.out.println( "aaa" ) ;
    else
      System.out.println( "bbb" ) ;
  
  // fragmento B
  if ( num > 0 )   
     if ( num < 10 ) 
        System.out.println( "aaa" ) ;
  else
     System.out.println( "bbb" ) ;
  

O compilador Java não considera indentação (o compilador Python considera), portanto os dois fragmentos de código acima são idênticos e vão ser executados da mesma forma. Qual das formas é a usada pelo compilador e como escrevemos o código que executa da outra maneira??

Quando queremos testar algo dentro de intervalos, por exemplo classificar pessoas por faixa de altura, é comum que apenas um de vários blocos de código seja executado. Para isso, pode-se usar uma estrutura if else if que tem indentação peculiar.

   class Sargento {
    public static void main (String[] args) {
     int altura=170; // altura em cm
     if (altura < 100) {
      System.out.println ("Anão");
     } else if (altura < 120){
      System.out.println ("Muito baixo");
     } else if (altura < 150){
      System.out.println ("Baixo");
     } else if (altura < 180){
      System.out.println ("Medio");
     } else if (altura < 200){
      System.out.println ("Alto");
     } else {
      System.out.println ("Gigante");
    }
   }
  

Switch

Quando queremos escolher uma entre várias alternativas, é comum usar os comandos switch..case. No switch é passada a variável a testar e nos case, cada alternativa.

     switch (<var>) {
      case <opcao1>:
       // comandos da opção 1
       break;  // salta para o próximo comando depois do switch
      case <opcao2>:
       // comandos da opção 2
       break;  // salta para o próximo comando depois do switch
      ......
      case <opcaoN>:
       // comandos da opção N
       break;  // salta para o próximo comando depois do switch
      default:   // caso não se enquadre em nenhum caso.
     }
  

Código exemplo:

   class Notas {
    public static void main (String[] args) {
     char nota='C';
     switch (nota) {
      case 'A':
       System.out.println ("Aprovado");
       break;
      case 'B':
       System.out.println ("Aprovado");
       break;
      case 'C':
       System.out.println ("Aprovado");
       break;
      case 'D':
       System.out.println ("Reprovado");
       break;
      case 'E':
       System.out.println ("Reprovado");
       break;
      default:
       System.out.println ("Erro de digitação.");
     }
    }
   }
  

Na execução do comando switch, a máquina virtual salta para o caso identificado e prossegue a execução em sequência. Como queremos que a execução seja interrompida (e que se salte para fora do switch) antes de atingir o próximo case, usa-se o comando break. Após executar o código acima, experimente remover os break e ver o que acontece. Teste também o código abaixo.

   class Notas {
    public static void main (String[] args) {
     char nota='C';
     switch (nota) {
      case 'A':
      case 'B':
      case 'C':
       System.out.println ("Aprovado");
       break;
      case 'D':
      case 'E':
       System.out.println ("Reprovado");
       break;
      default:
       System.out.println ("Erro de digitação.");
     }
    }
   }
  

<exprTeste>?<exprA>:<exprB>

Esta forma de escrever testes é especialmente útil quando se tratam expressões aritméticas. Por exemplo, se um número for par, divide por dois, se for ímpar, multiplica por três e soma 1.

   class Conta {
    public static void main (String[] args) {
     int n=100;
     n=((n%2)==0)?n/2:n*3+1;
    }
   }
  

Exercícios

Teste se um número é impar e imprima uma mensagem na tela.

Teste se um número é divisível por 7 e imprima uma mensagem na tela.

Teste se um número é divisível por 11 e por 13 e imprima mensagens na tela.

Teste se um número é divisível por 11 ou por 13 e imprima mensagens na tela.

Construa um questionário com duas questṍes de múltipla escolha de cinco alternativas cada.

Nenhum comentário:

Postar um comentário