segunda-feira, 26 de outubro de 2009

Deixe que o computador decida... Parte I (if)

Continuando a nossa jornada pelo C, hoje vamos falar sobre como o computador toma decisões.

O computador não pensa, mas pode tomar decisões!
Parece estranho isto que falei; afinal, todas as vezes que precisamos tomar decisões temos que pensar (embora algumas pessoas não o façam ;).
Pois bem, se ele não pensa, como faz isto? Simples! Alguém tem que pensar por ele! Quem seria este alguém??? Você, programador.
Criar programas é pensar pelo computador e, é o que já fazemos. Definimos as variáveis, os tipos, como os dados serão processados, o que será impresso, etc.
Para nos ajudar nesta tarefa de 'ensinar' o computador a tomar decisões, o C nos fornece os comandos de decisão e os operadores relacionais.
Hoje falaremos sobre o comando de decisão if e os operadores relacionais.

E se...?
Já reparou que temos que tomar decisões em função dos acontecimentos? Quando você vai sair de casa, logo olha para as condições climáticas. Seria algo, mais ou menos, assim:
Está calor agora, mas o céu está com nuvens. Levo guarda-chuva ou não? Mas, e se chover? Então, é melhor levar o guarda-chuva. Se chover, e somente se chover, eu faço uso do guarda-chuva, senão ele fica fechado.
O comando de decisão if faz exatamente isto. Vamos ver na prática, como ele funciona?

"O prevenido vale por dois!"
Se você se lembra do programa que usei como exemplo para explicar o uso do scanf (aqui), verá que no comando da linha 11, que explica ao usuário o que digitar para que o programa funcione, existe uma sugestão para que ele não digite o valor 0 (zero). Imagina, o por quê disto?
O resultado de uma divisão por zero é indeterminado. Como não se consegue determinar, evita-se fazer esta divisão.
Agora, me responda esta pergunta. E se o usuário, mesmo sendo avisado antes, digitar zero?
Na gíria dos programadores, o programa vai 'capotar'.
Os micros mais antigos, com sistemas operacionais também antigos, travavam de uma forma que, para voltar a funcionar, só desligando e ligando novamente (reboot); e com isto se perdia tudo o que não tinha sido salvo ainda.
Eu mesmo já perdi várias horas de digitação, porque um programa fez uma divisão por zero (runtime error division by zero). Como 'xinguei' o computador! Hoje sei, que 'xinguei' a 'pessoa' errada rsrs!
Evite ser xingado e use o comando if!
No caso do nosso exemplo seria só fazer assim:
- Antes de fazer a operação da linha 13, a divisão de num1 por num2, temos que avaliar o valor de num2.
Fácil, não é? E como se faz isto?
Resposta: Usando os operadores relacionais! Vamos a eles.

Operadores relacionais (Qual a relação entre laranjas e bananas?)
Antes de mostrar os operadores relacionais, vamos pensar no nosso exemplo.
Não queremos que o divisor da nossa divisão seja zero. Ele pode ser maior que zero, ou menor que zero. Só não pode ser zero! Tem que ser diferente.
Pensando assim, achamos a relação entre o nosso divisor (num2) e zero.
Se num2 for igual a zero, não poderemos efetuar a divisão. O programa será finalizado.
É exatamente isto que devemos 'dizer' ao computador que faça.
A forma de 'dizer' isto em C, é:

if (num2 == 0)
    exit(1);


Vamos por partes ;).
O if é o se da nossa frase em português, e significa exatamente isto em inglês (língua 'mãe' do C).
Dentro dos ( ) está a relação que estamos avaliando: num2 igual a zero.
Não estamos atribuindo o valor 0 (zero) a num2! Estamos avaliando/testando se a variável do lado esquerdo do == é igual a variável/valor do lado direito.
O == é um dos operadores operacionais, e avalia a igualdade entre variáveis e valores.
(O operador de atribuição é o =, e o operador relacional de igualdade é o ==. A confusão entre os 2 é muito comum, e gera erros de lógica que fazem muitos programadores queimarem neurônios por horas (rsrs). Preste muita atenção ao usar este operador relacional!)
A tabela abaixo mostra todos os operadores relacionais, e o que cada um significa.



Depois retornaremos a eles, com mais calma. Vamos continuar a análise, do nosso comando.
Na linha de baixo, temos o comando que encerra o nosso programa antes que ele execute a divisão.
E finalmente o ; que encerra o comando. Como assim, encerra?
Apesar de estar um duas linhas, este é um único comando. Poderia estar em uma única linha, mas está em duas por questões de clareza. Esta é uma caracteristica (não somente) do if: unir-se a outro comando formando um único.
Se quiser, altere o código, fazendo esta modificação, compile e execute; digite 0 (zero) para o valor do dividendo e veja o que acontece.
Esta alteração evita um 'capotamento' (rsrs), mas não deixa claro ao usuário o por quê do programa ser finalizado.
Não ficaria mais 'bonito' se fosse informado ao usuário a causa deste encerramento?
Então vamos alterar nosso código de novo para que isto seja feito.

if (num2 == 0)
    printf("O DIVIDENDO NÃO PODE SER ZERO! O programa será encerrado.\n");
    system("pause");
    exit(1);


Faça essas alterações no código, compile e execute.
O que aconteceu?
Conforme você deve ter notado, o programa encerra independente do valor do dividendo ser zero ou outro qualquer. Por que?
O comando if se encerra no ; . Portanto, para o computador os comandos seguintes NÃO fazem parte do if, e serão executados independente do if ser executado. Como corrigir isto?
Usando blocos! Que nada mais são que os sinais {, antes da sequência de comandos que queremos agrupar; e }, após estes comandos agrupados. Já falamos sobre isto aqui.
Assim nosso código ficará assim:


//Exemplo de if
//Exemplo de if

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


Ficou muito melhor, não é?
E se desejarmos que para o valor do dividendo só sejam aceitos números pares?
Veremos isto no próximo post.

Continua...

Nenhum comentário:

Postar um comentário