quarta-feira, 28 de outubro de 2009

Deixe que o computador decida... Parte III (operadores lógicos)

Vamos continuar aprendendo como o computador 'toma' descisões.
Hoje vamos ver os operadores lógicos e como eles facilitam a nossa vida quando precisamos tomar decisões baseadas em várias condições.

Duas descisões (ou mais!) de uma tacada só!
Dando uma olhada no nosso código exemplo do post anterior, podemos observar que para resolver a questão proposta tivemos que avaliar duas condições, se o divisor era zero e se o divisor era par. Estas avaliações são feitas nas linhas 15 e 18, respectivamente. Você sabia que poderíamos fazer estas duas avaliações de uma só vez!
Vamos pensar na questão proposta:
A divisão só será feita se o divisor não for igual a zero e se o divisor for um número par.
Sendo assim, a divisão só será realizada se as duas condições forem verdadeiras. Se apenas uma delas não for, a divisão não será realizada.
Poderíamos, analisar uma delas e, se não fosse verdadeira, provocar a saída abrupta do programa; se ela fosse verdadeira, passaríamos a análise da outra e, se ela não fosse verdadeira, provocar a saída abrupta do programa; se esta segunda avaliação desse um resultado verdadeiro, aí sim, a divisão seria realzada.


//Exemplo de avaliação de várias condições

#include <stdio.h>
#include <stdlib.h>

int main( )
{
 float num1, resultado;
 int num2;
 
 printf("Digite o numero que sera dividido(dividendo)\n");
 scanf("%f",&num1);
 printf("Digite o numero par que dividira o anterior (divisor), nao pode ser zero\n");
 scanf("%d",&num2);
 if (num2 == 0){
    printf("O DIVISOR NAO PODE SER ZERO! O programa sera encerrado.\n");
    system("pause");
    exit(1);
 }
 if (num2 % 2 != 0){
    printf("O DIVISOR NAO EH UM NUMERO PAR! O programa sera encerrado.\n");
    system("pause");
    exit(1);
 }
 resultado = num1 / num2;
 printf("O resultado da divisao de %.2f por %d eh igual a %.2f.\n",num1, num2, resultado);
 system ("pause");
}


Esta solução funciona, mas não é 'estéticamente' correta. Vejamos o porquê?
Quando fazemos alguma coisa, queremos que ela chegue até o seu final, e não seja interrompida antes disto. Com um programa não é diferente!
No começo deste mesmo post anterior, alteramos o nosso código para respeitar esse comportamento: ir até o final, mesmo que, por alguma entrada inválida do usuário, sua operação principal não fosse executada.
Usando os ifs aninhados do post anterior, conseguimos este efeito.
Mas existe uma forma mais 'bonita' (rsrs) de fazer isto: usando os operadores lógicos!

A lógica dos operadores
Os operadores lógicos são baseados nos conceitos de portas lógicas e lógica de Boole. O objetivo deles é 'unir' duas entradas e produzir uma única saída.
Podemos, com isto, 'unir' as duas condições avaliadas do nosso problema e, produzir uma única saída em função delas.
Existem 3 operadores lógicos em C: o && (and), o || (or) e o !(not).
O operador relacional not (!) tem por função produzir uma sáida que é o inverso da entrada. Tudo o que for verdadeiro se torna falso, e o que for falso se torna verdadeiro. O ! já é nosso conhecido, apesar de ainda não termos falado dele (rsrs). Lembra do operador relacional de igualdade (==), ele tem um oposto, que é o operador relacional diferente de (!=). Percebeu a presença do operador lógico not (!) neste operador relacional?
Ele está aí justamente para dar a idéia do inverso do igual a, ou seja, diferente de.

 !Verdadeiro => Falso

O operador relacional or (||) realiza uma 'soma' das entradas. De forma simples, se uma das entradas (ou as duas) for verdadeira, a saída será verdadeira. A saída só será falsa se as duas entradas forem falsas.

 Falso || Falso => Falso
 Falso || Verdadeiro => Verdadeiro
 Verdadeiro || Falso => Verdadeiro
 Verdadeiro || Verdadeiro => Verdadeiro

O operador relacional and (&&) realiza um 'produto' das entradas. De uma forma simples, se uma das entradas for falsa, a saída será falsa. A saída só será verdadeira se as duas entradas forem verdadeiras.

 Falso && Falso => Falso
 Falso && Verdadeiro => Falso
 Verdadeiro && Falso => Falso
 Verdadeiro && Verdadeiro => Verdadeiro

Entendeu a lógica dos operadores? Então responda:
Qual o operador lógico que devemos usar para resolver o nosso problema?

Acertou quem disse and (&&). Vamos ver porque?
Usando as seguintes avaliações:
num2 != 0; será verdadeiro se num2 for diferente de 0 (zero).
num2 % 2 == 0; será verdadeiro se o valor armazenado em num2 for par.

Se num2 for igual a zero, e o valor armazenado em num2 for impar teremos:
 Falso && Falso => Falso saída falsa

Se num2 for igual a zero, e o valor armazenado em num2 for par teremos:
 Falso && Verdadeiro => Falso saída falsa

Se num2 for diferente de zero, e o valor armazenado em num2 for impar teremos:
 Verdadeiro && Falso => Falso saída falsa

Se num2 for diferente de zero, e o valor armazenado em num2 for par teremos:
 Verdadeiro && Verdadeiro => Verdadeiro SAIDA VERDADEIRA

Usando os operadores relacionais, o nosso código ficará assim:

//Exemplo do uso de operadores lógicos

#include <stdio.h>
#include <stdlib.h>

int main( )
{
 float num1, resultado;
 int num2;
 
 printf("Digite o numero que sera dividido(dividendo)\n");
 scanf("%f",&num1);
 printf("Digite o numero par que dividira o anterior (divisor), nao pode ser zero\n");
 scanf("%d",&num2);
 if ((num2 != 0)&& (num2 % 2 == 0)){
    resultado = num1 / num2;
    printf("O resultado da divisao de %.2f por %d eh igual a %.2f.\n",num1, num2, resultado);
 }
 else
    printf("O DIVISOR NAO PODE SER NEM ZERO NEM IMPAR! O programa sera encerrado.\n");
 system ("pause");
}


Você não acha que o código ficou mais 'bonito' agora?

Hoje vimos como avaliar várias condições de entrada de uma forma melhor que com os ifs aninhados.
No próximo post veremos como agir quando uma mesma condição pode ter várias saídas.
Até lá.

Nenhum comentário:

Postar um comentário