sexta-feira, 30 de outubro de 2009

Deixe que o computador decida... Final ('curiosidades')

Vamos falar hoje sobre algumas 'curiosidades' dos comandos de decisão. Na verdade, não são bem 'curiosidades', são facilidades.

Como 'usar' o operador lógico || (or) com o switch?
Observe o código abaixo:


#include <stdio.h>
#include <stdlib.h>
 
int main(){
 char c;
 printf("Digite um caracter:\n->");
 scanf("%c",&c);
 if (c == 'a' ||c == 'e' ||c == 'i' || c == 'o' || c == 'u')
    printf(" Eh vogal!\n");
 else
    printf("Nao eh vogal!\n");
 system("pause");
}


O código acima recebe um caracter digitado pelo usuário e informa se é uma vogal ou não. Observe o uso do operador lógico || (or) para avaliar todas as 5 vogais (a, e, i, o, u). No entanto, se você compilar e executar este código, e entrar com uma vogal maiúscula (A, E, I, O, U), o programa dirá que não é uma vogal, já que ele só avalia as minúsculas. Poderíamos aumentar os || para avaliar também as maiúsculas.
Iria funcionar, com certeza; mas a linha de avaliação do if ficaria enorme.
Não poderíamos usar um comando switch para resolver isto?
Um código que nos vem a cabeça usando um comando switch seria algo assim:


#include <stdio.h>
#include <stdlib.h>
 
int main(){
 char c;
 printf("Digite um caracter:\n->");
 scanf("%c",&c);
 switch (c){
    case 'a':
       printf("Eh vogal!\n");
       break;
    case 'A':
       printf("Eh vogal!\n");
       break;
    case 'e':
       printf("Eh vogal!\n");
       break;
    case 'E':
       printf("Eh vogal!\n");
       break;
    case 'i':
       printf("Eh vogal!\n");
       break;
    case 'I':
       printf("Eh vogal!\n");
       break;
    case 'o':
       printf("Eh vogal!\n");
       break;
    case 'O':
       printf("Eh vogal!\n");
       break;
    case 'u':
       printf("Eh vogal!\n");
       break;
    case 'U':
       printf("Eh vogal!\n");
       break;
    default:
       printf("Nao eh vogal!\n");
 }
 system("pause");
}


O comando switch não era para reduzir o código??? (rsrs)
Era não, é! Mas o código ficou muito maior! O que deu errado?
Vamos analisar.
Podemos ver que existe uma repetição de comandos. Dentro dos cases que avaliam as vogais existem os mesmos comandos printfs e breaks.
O que fazer então para acabar com estas repetições desnecessárias?
Podemos usar os operadores lógicos || (or) para avaliar uma vogal minúscula e outra maiúscula?
A resposta é NÃO.
Não é possível fazer isto:

 case 'a' || 'A':

Dentro de cada case só pode haver um único valor.
Então não dá para usar o operador lógico || (or) junto com o comando switch?
Outra vez a resposta é NÃO.
Não podemos usar o operador lógico || (or), mas podemos conseguir o mesmo efeito dele.
Como? Veja o código abaixo:


#include <stdio.h>
#include <stdlib.h>
 
int main(){
 char c;
 printf("Digite um caracter:\n->");
 scanf("%c",&c);
 switch (c){
    case 'a':
    case 'A':
    case 'e':
    case 'E':
    case 'i':
    case 'I':
    case 'o':
    case 'O':
    case 'u':
    case 'U':
       printf("Eh vogal!\n");
       break;
    default:
       printf("Nao eh vogal!\n");
 }
 system("pause");
}


Este código ficou muito menor, e funciona perfeitamente para o propósito que foi criado. Pode compilar, executar e testar.
Não tem o mesmo efeito de usar o operador lógico || (or)?
Esta é uma 'curiosidade' do comando switch.
Quando encontra um case que corresponde ao valor avaliado, o comando switch executa os comandos que estão naquele case, até encontrar um comando break; se encontrar um outro case, ele ignora e 'segue em frente', e só para ao encontrar um comando break ou o final do bloco do comando switch.
Neste nosso código, a linha 19 será executada caso o caracter digitado for a, ou A, ou e, ou E, ou i, ou I, ou o, ou O, ou u, ou U.
Não é exatamente o efeito de usar um comando if com uma série de operadores lógicos || (or)?

Outra 'curiosidade' sobre o comando switch, é a possibilidade de utilizarmos, assim como no comando if, comandos switchs aninhados.
Observe este fragmento de código fonte abaixo:


 int x, y;
 .
 .
 .
 switch (x){
    case 1:
       switch (y){
          case 1:
 .
 .
 .
       }
 }
 .
 .
 .


Existem 2 cases com o mesmo valor 1:. Isto é perfeitamente possível, já que um se refere a variável x, e o outro a variável y.

A última 'curiosidade' que veremos hoje sobre os comandos de decisão, é a existência de um operador de decisão.

Operador de decisão ?
A linguagem C é muitas vezes considerada complicada pelo fato de usar algumas abreviações para comandos que são usados comumente.
Veremos estas abreviações mais a frente.
O comando de decisão if é um destes comandos usados com muita frequencia em códigos fonte, já que temos que tomar decisões que dependem dos dados quase que durante todo o tempo. Por isto, foi criado um operador de decisão que substitui um conjunto de comandos if-else simples.
Vejamos um exemplo.

 x = y > 10 ? 5 : 15;

O comando acima, atribui um valor a variável x que depende do valor da variável y. Se y for maior que 10, x receberá o valor 5, se não for, x receberá o valor 15.
Esta única linha substitui os comandos abaixo:


 if (y > 10)
    x = 5;
 else
    x = 15;


Em outras palavras, se a expressão avaliada (neste caso, y > 10) antes do operador de decisão (?), for verdadeira, o valor atribuido a variável (neste caso, x) será o valor imediatamente após o operador de decisão (?)(neste caso, 5); se não for verdadeira, ou melhor dizendo, for falsa, o valor atribuido a variável será o valor que está após o :.

Assim encerramos esta série sobre os comandos de decisão.
No próximo post veremos outras abreviações usadas no C. Até lá.

Nenhum comentário:

Postar um comentário