Mostrando postagens com marcador switch. Mostrar todas as postagens
Mostrando postagens com marcador switch. Mostrar todas as postagens

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á.

quinta-feira, 29 de outubro de 2009

Deixe que o computador decida... Parte IV (switch)

Hoje vamos seguir conhecendo os comandos de decisão do C.

Já vimos como tomar decisões que produzem saídas simples, do tipo faça ou não faça.
E quando as possibilidades de saídas aumentam?
Imagine um programa para imprimir o nome de um mês de acordo com o número deste mês.
Usando as regras de indentação, o código fonte vai ficando cada vez maior à medida que acrescentamos novas avaliações.



//PROGRAMA PARA IMPRIMIR O MÊS DE ACORDO COM O NÚMERO
//USANDO IFs ANINHADOS
#include <stdio.h>
#include <stdlib.h>
 
int main(){
 int mes;
 
 printf("Digite os digitos do mes:\n->");
 scanf("%d",&mes);
 if (mes == 1)
    printf("Janeiro\n");
 else
    if (mes == 2)
        printf("Fevereiro\n");
    else
        if (mes == 3)
            printf("Marco\n");
        else
            if (mes == 4)
                printf("Abril\n");
    .
    .
    .
    .
 else
    printf("O valor nao corresponde a um mes!\n");
 system("pause");
}


Para evitar esta progressão geométrica de aumento de espaços e tabulações (tanto que não pude colocar todo o código aqui, devido as limitações de espaço de exibição), O C nos dá a opção de usar o comando switch.

Uma lista de opções
Você já deve ter visto várias listas de opções: uma opção embaixo da outra, facilitando a visualização de todas elas.
O comando switch se parece com uma lista destas.
Olhe como ficaria o código acima usando o switch:


//PROGRAMA PARA IMPRIMIR O MÊS DE ACORDO COM O NÚMERO
//USANDO SWITCH
#include <stdio.h>
#include <stdlib.h>
 
int main(){
 int mes;
 
 printf("Digite os digitos do mes:\n->");
 scanf("%d",&mes);
 switch (mes){
    case 1:
       printf("Janeiro\n");
       break;
    case 2:
       printf("Fevereiro\n");
       break;
    case 3:
       printf("Marco\n");
       break;
    case 4:
       printf("Abril\n");
       break;
    case 5:
       printf("Maio\n");
       break;
    case 6:
       printf("Junho\n");
       break;
    case 7:
       printf("Julho\n");
       break;
    case 8:
       printf("Agosto\n");
       break;
    case 9:
       printf("Setembro\n");
       break;
    case 10:
       printf("Outubro\n");
       break;
    case 11:
       printf("Novembro\n");
       break;
    case 12:
       printf("Dezembro\n");
       break;
    default:
       printf("O valor nao corresponde a um mes!\n");
 }
 system("pause");
}


Algumas coisas chamam a atenção neste código.
A 1ª delas é a forma de uso do switch da linha 11. Entre os () fica a variável que será avaliada. O switch só trabalha com variáveis dos tipos char e int. Além disto, observe o uso de {} para indicar as opções que serão avaliadas.
A 2ª coisa que devemos reparar é na palavra case, que aparece pela 1ª vez na linha 12, seguida pelo número 1 e um :. Aqui aparece o valor que a variável avaliada pode assumir, neste caso 1.
Se a variável tiver um valor igual ao que segue a palavra case, os comandos abaixo deste case serão executados até o comando break.
O comando break encerra o switch, ou seja, o programa 'salta' para o comando seguinte ao bloco do switch. Ele é chamado de comando de desvio; e, além do switch, também pode trabalhar em conjunto com outros comandos, como veremos mais a frente em nossos estudos.
A 3ª coisa que devemos reparar é na palavra default, que aparece na linha 48, também seguida por :. O uso do default é opcional. Mas se usado, ele deve ser colocado abaixo de todas as opções possíveis, antes do fim do bloco do switch.
Se a variável não tiver um valor igual a nenhum dos anteriores, os comandos abaixo dele serão executados. Observe que após o default não é necessário o uso do comando break, já que não existem opções depois dele, e o switch será mesmo finalizado.

O switch é simples, mas muito útil. Veremos mais sobre algumas características dele no próximo post, onde encerraremos nossa série sobre os comandos de decisão, vendo algumas curiosidades sobre os comandos de decisão.

Até lá.

PS: O que você está achando do blog? Tem alguma coisa que não ficou clara? Ou que você tem uma forma melhor de explicar? COMENTE! Ajude a tornar este blog melhor!