quinta-feira, 20 de março de 2008

La vêm as chaves, chaves, chaves....

O título é uma brincadeira com o nome do personagem da tv.
As chaves delimitam um bloco de comandos na linguagem C e isso foi comentado no post Anatomia do programa em C.
Elas voltaram a aparecer na estrutura condicional, e é claro, delimitando um bloco de comandos tanto para o if quanto para o else.
Quando uma expressão condicional, localizada no if, é verdadeira, o bloco de comandos (que fica entre chaves) logo abaixo do if é executado. Na verdade, as chaves são obrigatórias quando o bloco de comando possui mais de uma linha de comando a ser executada. Quando existe somente uma linha de comando, as chaves passam a ser opcional. Isso, isso, isso, isso, .... Opcional!
Recorrendo novamente a divisão, temos:


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    float numerador, denominador;
007:    
008:    printf("Digite o numerador: ");
009:    fflush(stdin);scanf("%f", &numerador);
010:    printf("Digite o denominador: ");
011:    fflush(stdin);scanf("%f", &denominador);
012:    if(denominador != 0)
013:      printf("Resultado da divisao: %f\n", numerador/denominador);
014:    else
015:      printf("Nao e possivel fazer divisao por zero!\n");
016:    system("PAUSE");
017:    return 0;
018:  }


Na minha opinião, o uso das chaves auxilia a leitura do código e ainda insere um fator de segurança quando uma manutenção do código inclui mais linhas nos blocos de comando. Essa prática minimiza a ocorrência do esquecimento desenvolvedor em incluir as chaves quando ele insere as novas linhas. Esquecer as chaves quando necessárias causam grandes aborrecimentos e afinal, o esquecimento "foi sem querer, querendo!".
Eu uso sempre as chaves, exceto no else if, porque não quero ficar chorando por aí. "Pi, pi, pi, pi, pi".

terça-feira, 18 de março de 2008

Condicional composto

O condicional simples resolve apenas uma pequena parte dos problemas de programação. É interessante testar uma condição e se ela for falsa, tomar alguma decisão. Isso é possível com o condicional composto.


SE condicao ENTAO
  comando_001;
  comando_002;
SENAO
  comando_003;
  comando_004;
FIM SE


Os comandos 001 e 002 serão executados sempre que o valor de condicao for verdadeiro e os comandos 003 e 004 serão executados sempre que a condição for falsa.
Na linguagem C, o condicional composto é expresso por:


if(condicao)
{
  comando_001;
  comando_002;
}
else
{
  comando_003;
  comando_004;
}


Tal como no condicional simples, utilizarei a divisão para ilustrar o funcionamento do condicional composto em linguagem C.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    float numerador, denominador;
007:    
008:    printf("Digite o numerador: ");
009:    fflush(stdin);scanf("%f", &numerador);
010:    printf("Digite o denominador: ");
011:    fflush(stdin);scanf("%f", &denominador);
012:    if(denominador != 0)
013:    {
014:      printf("Resultado da divisao: %f\n", numerador/denominador);
015:    }
016:    else
017:    {
018:      printf("Nao e possivel fazer divisao por zero!\n");
019:    }
020:    system("PAUSE");
021:    return 0;
022:  }


O código acima avalia se o denominador é diferente de zero para efetuar a divisão. Quando o denominador é igual a zero, o programa informa ao usuário que a divisão por zero é impossível.
Sugiro a leitura dos posts Qual a negação do maior e Qual a negação do OU por estarem intimamente ligados ao SENAO de uma estrutura SE.

sexta-feira, 14 de março de 2008

Qual a negação do OU?

Pense bem antes de responder!!!!
A negação da operação lógica OU não é a operação lógica E.
Vamos demonstrar por meio de um exemplo prático! Suponha a seguinte condição idade <= 10 || idade > 20 como necessária a uma pesquisa de opinião, que visa consultar pessoas fora da idade da adolescência.
A tabela verdade para a seguinte expressão é:
idade <= 10idade > 20idade <= 10 || idade > 20
FFF
FVV
VFV
VVV

Considerando idade uma variável inteira, para a primeira proposição temos valores de idade entre 10 e 19 anos, o que torna falso a expressão (condição de adolescentes).
Na segunda proposição temos valores de idade maiores que 20, ou seja, não existem (matematicamente falando) adolescentes cuja idade é superior a vinte anos.
Na terceira proposição temos valores de idade menores ou iguais a 10, ou seja crianças.
A quarta proposição é matematicamente impossível porque não existem valores de idade que satisfaçam a equação. Se você conhece um valor de idade que ao mesmo tempo é maior que 20 e menor ou igual a 10, por favor, me avise!
Agora vamos analisar a negação da expressão e ver o que acontece.
idade <= 10idade > 20!(idade <= 10 || idade > 20)
FFV
FVF
VFF
VVF

Como é de se esperar, o resultado final é invertido, em outras palavras, a negação é verdadeira para a faixa de idade que compreende a adolescência.
Comparando com a operação E, o resultado não é o mesmo! Veja a tabela verdade abaixo:
idade <= 10idade > 20idade <= 10 && idade > 20
FFF
FVF
VFF
VVV

Note que a primeira e a última linha da negação do OU e da operação E não coincidem, o que mostra que não são operações equivalentes. Uma outra curiosidade nesse caso, a operação E nunca será verdadeira porque não existe valor de idade que é menor ou igual a 10 E maior que 20.
Pelo exemplo, a negação da expressão limitou os valores que compreendem a adolescência, ou seja valores de idade maior que 10 E menor ou igual a 20, que expresso em linguagem C fica idade > 10 && idade <= 20
Vamos novamente recorrer a tabela verdade, considerando a nova expressão.
idade > 10idade <= 20idade > 10 && idade <= 20
VVV
VFF
FVF
FFF

Note o resultado dessa tabela verdade com a segunda... São iguais!!!
Agora note os operandos... Eles são os complementos lógicos dos operandos da segunda tabela!!!
O que ocorreu com a operação lógica? Veja que a operação lógica OU foi trocada pela E.
O que você acabou de verificar foi a aplicação da lei de De Morgan que diz:
!(A || B) == !A && !B
!(A && B) == !A || !B
Finalizando, a negação das operações lógicas E e OU é facilmente resolvida pela lei de De Morgan.

segunda-feira, 10 de março de 2008

Qual a negação do maior?

Se sua resposta é menor, então deverá ler esse post.
Essa é uma questão puramente matemática, mas de fundamental importância para compreender o famoso senão da estrutura condicional.
O conceito da negação de uma expressão condicional está ligado a operação lógica não, afinal a expressão relacional retorna verdadeiro ou falso, a negação dessa expressão é, na verdade, negar o seu resultado.
Voltando a pergunta, qual a negação do maior, a resposta é menor ou igual a.
A expressão idade > 30 será verdadeira quando idade (supondo uma variável inteira) valer 31, 32, 33, ..., +infinito; e falsa para 30, 29, 28, ..., -infinito.
Analisando !(idade > 30) os valores esperados são falso para valores de idade iguais a 31, 32, 33, ..., +infinito; e verdadeiro para 30, 29, 28, ..., -infinito. Acho um pouco ilegível esse tipo de expressão, porque você deve analisar a desigualdade e após negar o resultado. O mais correto é usar o complemento lógico, ou seja, idade <= 30.
Segue uma lista do complemento lógico das operações relacionais existentes:

operaçãocomplemento
==!=
><=
>=<
<>=
<=>

sexta-feira, 7 de março de 2008

Condicional simples

O mais interessante quando programamos é a sensação de poder que temos sobre o destino dos dados. Quando escrevemos um programa, nada mais fazemos do que determinar qual tratamento será dado para os dados que alimentam o programa.
Os dados sofrem transformações, são utilizados ou descartados de acordo com seu valor. Para inferir os valores, usamos as estruturas condicionais. Elas são capazes de desviar o fluxo de processamento de acordo com o valor de uma ou mais variáveis.
A mais simples das estruturas condicionais é o se.


SE condicao ENTAO
  comando_001;
  comando_002;
  ...
  comando_nnn;
FIM SE


Os comandos serão executados sempre que o valor de condicao for verdadeiro.
condicao pode ser uma expressão relacional simples ou encadeada com vários operadores lógicos.
Na linguagem C, o condicional simples é expresso por:


if(condicao)
{
  comando_001;
  comando_002;
  ...
  comando_nnn;
}


Utilizarei a divisão para ilustrar o funcionamento do condicional simples em linguagem C.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    float numerador, denominador;
007:    
008:    printf("Digite o numerador: ");
009:    fflush(stdin);scanf("%f", &numerador);
010:    printf("Digite o denominador: ");
011:    fflush(stdin);scanf("%f", &denominador);
012:    if(denominador != 0)
013:    {
014:      printf("Resultado da divisao: %f\n", numerador/denominador);
015:    }
016:    system("PAUSE");
017:    return 0;
018:  }


O código acima avalia se o denominador é diferente de zero para efetuar a divisão. Sabe-se que na aritmética, não existe a divisão por zero, portanto implementamos essa regra de negócio para que a divisão ocorra sem problemas.
Apenas como curiosidade, o estudo de limites, trata da divisão por zero.
Parabéns, você acaba de receber um pequeno poder para definir o destino de alguns dados. Seja benevolente com eles....

quarta-feira, 5 de março de 2008

Operadores lógicos

Existem três operações lógicas básicas, a operação E, a OU e a NÃO, as quais operam com valores lógicos verdadeiro(V) ou falso(F).
A operação E e a OU, exigem dois operandos, já a NÃO exige somente um.
A operação E será verdadeira quando os dois operandos forem verdadeiros, elá valerá falso quando ao menos um dos operandos for falso.
ABA E B
FFF
FVF
VFF
VVV

A operação OU retornará verdadeiro quando pelo menos um dos operandos for verdadeiro, elá retornará falso quando os dois operandos forem falsos.
ABA OU B
FFF
FVV
VFV
VVV

A operação lógica NÃO, inverte o valor lógico do operando, ou seja, será verdadeira quando o operando for falso e falso quando o operando valer verdadeiro. Essa operação é também chamada de complemento.
ANÃO A
VF
FV

Os operadores lógicos são representados em liguagem C pelos seguintes tokens.
  1. (&&) E
  2. (||) OU
  3. (!) NÃO

Os operandos podem ser números, expressões relacionais, etc...
O programa abaixo mostra o resultado das operações E, OU e NÃO para valores de A e B digitados pelo usuário.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    int A, B;
008:
009:    printf("Digite o valor de A: ");
010:    fflush(stdin);scanf("%d", &A);
011:    printf("Digite o valor de B: ");
012:    fflush(stdin);scanf("%d", &B);
013:    printf("A E B: %d\n", A && B);
014:    printf("A OU B: %d\n", A || B);
015:    printf("NAO A: %d\n", !A);
016:    printf("NAO B: %d\n", !B);
017:    system("PAUSE");
018:    return 0;
019:  }


A saída esperada para A valendo 0 (Falso) e B valendo 1 (Verdadeiro)


Digite o valor de A: 0
Digite o valor de B: 1
A E B: 0
A OU B: 1
NAO A: 1
NAO B: 0

segunda-feira, 3 de março de 2008

Aqui vírgula é ponto!

Os iniciantes em linguagem C costumam confundir vírgula com ponto ou vice-e-versa.
Para os norte americanos, criadores da linguagem, o separador decimal é ponto e o de milhar é vírgula.
O número 10.326 para a linguagem C é dez inteiros e trezentos e vinte e seis milésimos, ou 10 + (float)326/1000.
Você se enganou se pensou que o número é dez mil e trezentos e vinte e seis.
Quando você programar, não utilize separador de milhar. A linguagem C utiliza a vírgula de forma reservada, portanto não dará certo;
Para separador de decimal, utilize o ponto.



001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    float decimal, milhar;
007:    
007:    decimal = 10.326;
007:    milhar = 10326;
008:    printf("Decimal: %f\nMilhar: %f", decimal, milhar);
009:    system("PAUSE");
010:    return 0;
011:  }


A saída esperada é:


Decimal: 10.326000
Milhar: 10326.000000


Espero que fique bem claro que aqui, vírgula é ponto. :D