sábado, 9 de agosto de 2008

Do while

Do while

O do while é um laço de repetição que executa primeiro o bloco de comandos e depois testa a condição. Caso a condição seja verdadeira, o laço é executado novamente. Quando a condição é falsa, a execução do laço é terminada.
Essa característica de executar e depois testar, garante que o laço será executado ao menos uma vez, diferentemente do while, o qual não executa quando sua condição é falsa.
A validação de entrada é um exemplo pertinente para o uso do do while, uma vez que a leitura do dado deverá ser executada ao menos uma vez. Quando o dado não é consistente com o conjunto de dados esperados, uma nova leitura é solicitada.
Veja o exemplo abaixo:



001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char * argv[])
005:  {
006:    char sexo;
007:
008:    do
009:    {
010:      printf("Digite o sexo: ");
011:      fflush(stdin); scanf("%c", &sexo);
012:      if(sexo != 'M' && sexo != 'F')
013:      {
014:        printf("Digite M ou F\n");
015:      }
016:    }while(sexo != 'M' && sexo != 'F');
017:    system("PAUSE");
018:    return 0;
019:  }



Note que o código é feito para importunar o usuário de forma que ele digite M para masculino ou F para feminino. Em outras palavras, o programa ficará em loop até que M ou F seja digitado. Baseado nisso, posso afirmar que a condição de saída do laço é M ou F.
Com este post finalizei a trilogia de laços de repetição, o que não quer dizer que esgotei o assunto...

quinta-feira, 7 de agosto de 2008

While

Retomando o assunto Laços de Repetição, abordado em abril/2008, hoje vamos tratar do while.
A forma geral desse laço é:

while


while(condicao)
{
  comandos...
}


É importante saber que dentro do bloco de comandos do while é necessário tornar a condicao falsa. Caso isso não ocorra, o while entrará em loop infinito.

Vamos recorrer a um exemplo simples:
Suponha que uma cidade A possua 1.500.000 habitantes e taxa de crescimento anual de 1%. Suponha também que uma cidade B com 500.000 habitantes cresce anualmente a 3%. Você deseja saber em quantos anos, mantendo-se as taxas de crescimento, a população de B será maior que a população de A.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char * argv[])
005:  {
006:    int anos=0;
007:    float popA=1.5, popB = 0.5;
008:
009:    while(popA >= popB)
010:    {
011:      popA = 1.01 * popA;
012:      popB = 1.03 * popB;
013:      anos += 1;
014:    }
015:    printf(“Quantidade de anos necessaria: %d\n”, anos);
016:    system("PAUSE");
017:    return 0;
018:  }


O exemplo mostra que enquanto a condição for verdadeira, ou seja, a população de A for maior ou igual a B, os anos passam (linha 13), e a população cresce (linhas 11 e 12).
Os dados de população e taxa de crescimento possibilitam que em algum ano, a população da cidade B será maior que a de A.
Caso a taxa de crescimento de A fosse maior que a de B, nunca a condição de saída seria atingida.
Sempre que trabalhar com o while, verifique a condição e identifique quais linhas tornarão seu resultado falso e se isso acontecerá. Com essa verificação seu laço não entrará em loop infinito.
Agora farei algumas considerações com relação aos cálculos praticados nas linhas 11 e 12, os quais podem parecer obscuros a alguém.
A linha 11 poderia ser reescrita como:


popA = popA + 1.0/100 * popA;



Dividindo 1.0/100 temos:



popA = popA + 0.01 * popA;



Colocando popA em evidência temos:



popA = (1 + 0.01) * popA;



Efetuando a soma 1 + 0.01 fica:



popA = 1.01 * popA;



Bendita ou maldita matemática. :D

quarta-feira, 23 de abril de 2008

For

No tópico Laços de Repetição foram abordados de forma geral os três laços possíveis na linguagem C.
Esse tópico trata do laço for.
Como visto, a forma geral desse laço é:

for


for(variavel = valor_inicial; condicao_envolvendo_variavel; incremento/decremento de variavel)
{
  comandos...
}


Vamos vê-lo na prática:


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char * argv[])
005:  {
006:    int i;
007:
008:    for(i = 0; i < 10; i++)
009:    {
010:      printf("%d\n", i);
011:    }
012:    system("PAUSE");
013:    return 0;
014:  }


O exemplo, embora simples, ilustra que o início do for é bem definido, bem como seu fim. Note que a variável i inicia com 0 e termina com 10.
Quando estou em sala de aula sempre pergunto quantas vezes o for será executado. A resposta é 10 vezes, com i variando de 0 a 9 (i < 10).
Se não confia em mim, execute o código acima e verifique as impressões do valor de i. Deverá aparecer 0, 1, ..., 9.
Outra pergunta que costumo fazer é qual o valor de i após a execução do laço for, em outras palavras, se imprimisse o valor de i na linha 012, o que seria impresso? A resposta correta é 10, lembre-se que existe uma condição para o for ser abandonado (i < 10). Quando i valer 10, o laço termina a sua execução.
Agora vamos ao exemplo prático. Vamos calcular o fatorial de um número inteiro.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    int fat = 1, n, i;
007:
008:    printf("Digite o numero: ");
009:    fflush(stdin); scanf("%d", &n);
010:
011:    if (n < 0)
012:    {
013:      printf("Nao existe fatorial de numero negativo.\n");
014:    }
015:    else
016:    {
017:        for(i = n; i > 1; i--)
018:        {
019:            fat *= i;
020:        }
021:        printf("%d! = %d\n", n, fat);
022:    }
023:    system("PAUSE");
024:    return 0;
025:  }


Verifique o início e o fim do laço, novamente bem definidos! Inicia em n e termina em 1.
A linguagem C permite que você altere, dentro do laço, os valores da variável de controle (i). Essa não é uma prática recomendável porque esse laço perde sua característica de executar um número determinado de vezes. Se você alterar os valores da variável de controle, não poderá garantir quantas vezes o laço será executado.

Laços de repetição

Os laços de repetição são ferramentas poderosas para o controle do fluxo de execução do programa. Eles permitem que um determinado trecho de código seja executado até que uma condição específica seja satisfeita.
A linguagem C possui três tipos de laço de repetição, a saber, o for (para), o while (enquanto) e o do while (faça enquanto).
O for deve ser utilizado quando você sabe o número de vezes em que o laço será executado. Por exemplo, o cálculo do fatorial de n, no qual sabe-se de antemão que o laço será executado n-1-vezes.
O while e o do while devem ser empregados quando não sabemos o número de vezes em que o laço será executado, por exemplo, quando pretende-se saber em quantos anos a população da cidade A será maior que a população da cidade B.
Existe uma particularidade entre o while e o do while. O bloco while pode nunca ser executado, caso a condição seja falsa logo na primeira tentativa. O do while executa o bloco e depois verifica a condição, portanto, ele será executado ao menos uma vez.
A forma geral de cada um dos laços é apresentada a seguir:

for


for(variavel = valor_inicial; condicao_envolvendo_variavel; incremento/decremento de variavel)
{
  comandos...
}



while


while(condicao)
{
  comandos...
  /*Não esqueça de que os comandos devem, de alguma forma, alterar condicao*/
}



do while


do
{
  comandos...
  /*Não esqueça de que os comandos devem, de alguma forma, alterar condicao*/
} while(condicao);



Nas estruturas while e o do while você deve alterar a condição, dentro do bloco, para que de alguma forma o laço tenha fim. Se isso não ocorrer, o programa entrará no chamado loop infinito.
Seu poder sobre o destino dos dados estão aumentando. Use-o com cautela.

terça-feira, 22 de abril de 2008

Está indeciso?

Esse não é um tópico de auto-ajuda e muito menos de auto-conhecimento. :-)
A intenção aqui é mostrar que quando possuímos várias decisões, podemos utilizar um comando especial, chamado de switch.
Esse comando avalia uma variável e toma uma decisão de acordo com seu valor.
Um exemplo vale mais que mil palavras. Suponha que você deve construir uma pequena calculadora de quatro operações básicas. É natural que sua calculadora tenha uma variável para armazenar qual operação ela deverá fazer. Avaliando essa variável ('+', '-', '*', '/') você procederá com a operação.
Você poderá fazer da seguinte forma:


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char op;
007:    int v1, v2;
008:
009:    printf("Digite a operacao: ");
010:    fflush(stdin);scanf("%c", &op);
011:    printf("Digite o primeiro valor: ");
012:    fflush(stdin);scanf("%d", &v1);
013:    printf("Digite o segundo valor: ");
014:    fflush(stdin);scanf("%d", &v2);
015:    if(op == '+')
016:    {
017:      printf("Soma: %d\n", v1 + v2);
018:    }
019:    else if(op == '-')
020:    {
021:      printf("Subtracao: %d\n", v1 - v2);
022:    }
023:    else if(op == '*')
024:    {
025:      printf("Multiplicacao: %d\n", v1 * v2);
026:    }
027:    else if(op == '/')
028:    {
029:      if (v2 != 0)
030:      {
031:        printf("Divisao: %d\n", v1 / v2);
032:      }
033:      else
034:      {
035:        printf("Denominador igual a zero.\n");
036:      }
037:    }
038:    else
039:    {
040:      printf("Operacao invalida\n.");
041:    }
042:    system("PAUSE");
043:    return 0;
044:  }


Que festival de else ifs! O código não fica muito elegante. Com a estrutura switch a coisa muda de figura.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char * argv[])
005:  {
006:    char op;
007:    int v1, v2;
008:
009:    printf("Digite a operacao: ");
010:    fflush(stdin);scanf("%c", &op);
011:    printf("Digite o primeiro valor: ");
012:    fflush(stdin);scanf("%d", &v1);
013:    printf("Digite o segundo valor: ");
014:    fflush(stdin);scanf("%d", &v2);
015:
016:    switch(op)
017:    {
018:      case '+': printf("Soma: %d\n", v1 + v2);
019:                break;
020:      case '-': printf("Subtracao: %d\n", v1 - v2);
021:                break;
022:      case '*': printf("Multiplicacao: %d\n", v1 * v2);
023:                break;
024:      case '/': if(v2 != 0)
025:                {
026:                  printf("Divisao: %d\n", v1 + v2);
027:                }
028:                else
029:                {
030:                  printf("Denominador igual a zero.\n");
031:                }
032:                break;
033:      default:
034:                printf("Operacao invalida!\n");
035:
036:    }
037:    system("PAUSE");
038:    return 0;
039:  }


Note que existe um caso (case) para cada valor de op. Note também que cada bloco de comandos inicia com um case constante: e termina com um break. Se o valor avaliado não existe na lista de opções, será executado o bloco de comandos padrão, chamado de default.
Muitos alunos me questionam se o default é necessário. A resposta é "Se o seu problema exigir um tratamento padrão, use o default, caso contrário não é necessário".
É importante saber que o switch funciona somente com variáveis do tipo inteiro, lembre-se que o char é um deles.
Aproveite essa estrutura para melhorar seus códigos.

E o else if?

Quando abordo as questões relativas aos comandos de decisões, muitos alunos me perguntam como devem proceder para escrever o camando else if.
Primeiramente respondo que não existe esse comando. Mas como explicar construção abaixo?


if(condicao)
{
  comandos...
} else if (condicao 2)
{
   mais comandos...
}


Lembra-se que no tópico Lá vêm as chaves, chaves, chaves... eu disse que as chaves são opcionais quando temos apenas uma linha de comando?
Então, o tal comando else if nada mais é do que uma utilização desse conceito. Veja dessa forma:


if(condicao)
{
  comandos...
} else
  if (condicao 2)
  {
     mais comandos...
  }


O que temos após o else é um comando de uma linha somente, o if, o qual pode ter n linhas dentro de seu bloco.
Usem a construção else if da primeira forma apresentada, ela tem melhor legibilidade.

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

quarta-feira, 27 de fevereiro de 2008

Verdadeiro e falso

A linguagem c não possui um tipo de dado booleano, então de que forma ele trada o que é verdadeiro e falso?
Sabe-se que para a linguagem C tudo o que tiver valor 0 é falso e tudo o que for diferente de 0 é verdadeiro.
Para fins de demonstração recorrerei a dois exemplos.
O primeiro exemplo apresenta o valor numérico de duas expressões lógicas, uma verdadeira e outra falsa.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo = 'F';
007:    
008:    printf("sexo igual a F: %d\n", sexo == 'F');
009:    printf("sexo igual a M: %d\n", sexo == 'M');
010:    system("PAUSE");
011:    return 0;
012:  }


A saída produzida pelo programa deve ser


sexo igual a F: 1
sexo igual a M: 0


Como o sexo vale F, quando é feita a relação entre sexo e M, o resultado é falso(0). Quando a relação é estabelecida entre sexo e F, o resultado é verdadeiro (diferente de 0, nesse caso 1).
O segundo exemplo é para provar que valores diferentes de zero são considerados verdadeiros.
A estrutura de decisão if (se) avalia uma variável ou expressão e decide se executará seu bloco verdade ou seu bloco falsidade.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    int valor;
008:    
009:    printf("Digite um valor inteiro: ");
010:    fflush(stdin);scanf("%d", &valor);
011:    if(valor)
012:    {
013:      printf("Valor diferente de zero: %d\n", valor);
014:    }
015:    else
016:    {
017:      printf("Valor igual a zero: %d\n", valor);
018:    }
019:    system("PAUSE");
020:    return 0;
021:  }


Na execução do programa, se você digitar 0, a saída do programa é


Valor igual a zero: 0


ou seja a instrução if (valor), pode ser traduzida para if(0), ou ainda, em português estruturado se falso então. Isso sempre executara o bloco else do if.
Quando você digita um valor diferente de zero, suponha 5, a saída esperada é


Valor diferente de zero: 5


então a instrução if (valor), é equivalente a if (5), que equivale a se verdade então.
Espero que as demonstrações sejam suficientes para você guardar que 0 é falso e diferente de zero é verdadeiro. :-D

Operadores relacionais

Os operadores relacionais estabelecem uma relação (Não poderia ser mais óbvio!) entre seus operandos.
Essa relação pode ser de:
  1. (==) igualdade
  2. (!=) diferença
  3. (>) maior que
  4. (<) menor que
  5. (>=) maior ou igual a
  6. (<=) menor ou igual a

É interessante saber que o resultado de uma expressão relacional é sempre lógico, ou seja, retorna verdadeiro ou falso.
Analisando a equação relacional


X == 7;


concluímos que o resultado será verdadeiro para X igual a 7 e falso para X diferente de 7.
Algumas vezes a análise não é tão simples assim. Por exemplo:


X > 7;


O resultado será verdadeiro para qualquer valor real maior ou igual a 7.
Quando o resultado será falso? Alguns respondem, de primeira, quando X for menor que 7 e esquecem que quando X é igual a 7 o resultado da expressão também é falso.
A resposta correta é quando X for menor ou igual a 7.
Sempre que deparar com uma relação, tente identificar os conjuntos de valores que a tornam verdadeira e falsa, assim você terá domínio maior sobre o problema.

segunda-feira, 25 de fevereiro de 2008

O scanf engana

Quando falei sobre a função scanf, chamei a atenção para a limpeza do buffer do teclado.
Naquele momento enfatizei que limpar o buffer do teclado evitaria algumas dores de cabeça.
Execute o código abaixo e verifique o seu funcionamento.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char chr1, chr2;
007:    
008:    printf("Digite o primeiro caractere: ");
009:    scanf("%c", &chr1
010:    printf("Digite o segundo caractere: ");
011:    scanf("%c", &chr2);
012:    printf("Primeiro caractere %c\nSegundo caractere: %c\n", chr1, chr2);
013:    system("PAUSE");
014:    return 0;
015:  }


Não fique nervoso tentando digitar o segundo caractere. Esse problema é bastante comum nos códigos de programadores pouco experientes. Tente limpar o buffer do teclado, utilizando a instrução fflush(stdin) antes de cada scanf. Você verá que agora o segundo caractere é lido.
Por que isso ocorre? Imagine o buffer do teclado como um arquivo seqüencial, onde o scanf retira os dados.
Para o exemplo anterior, na linha 9, o scanf espera que você digite um byte (estamos lendo variáveis do tipo char). O que você faz? Digita o caractere e em seguida o enter. Supondo que você digitou o caractere V, o buffer do teclado fica:


V\n


O \n representa o enter.
Após a execução da linha 9, o caractere V é armazenado na variável chr1, deixando o \n no buffer do teclado. Adivinhe que receberá o \n? Correto, a variável chr2. Por esse motivo ela não é lida!
Quando você usa a instrução fflush(stdin), e limpa o buffer do teclado, o \n sai do buffer, deixando ele limpo para a próxima leitura.

Operadores aritméticos

A linguagem C disponibiliza cinco operadores aritméticos binários.
  1. (+) soma
  2. (-) subtração
  3. (*) multiplicação
  4. (/) divisão
  5. (%) resto de uma divisão entre inteiros

Os operadores binários recebem esse nome porque necessitam de dois operandos para que a operação exista.


x = a + b;


Nem todas as operações são binárias. A linguagem C disponibiliza a operação menos unário, a qual necessita somente de um operando para existir.


x = -a;


O menos unário é equivalente a multiplicação por -1. Estere aí! Na multiplicação por -1 não estamos empregando o menos unário no operando 1. Olhe o código abaixo e conclua!


x = -1 * a;


Todas as operações são aplicadas a números inteiros e de ponto flutuante, com exeção do resto.
O conceito de resto de uma divisão só existe quando falamos em números inteiros, portanto o operador % exige que seus operandos sejam do tipo int ou char.
De todas as operações, a mais ingrata é a divisão.
Você é capaz de responder o que será impresso pelo seguinte código?


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    int a = 5, b = 2;
007:    float c;
008:    c = a/b;
009:    printf("O resultado da divisao e: %f", c);
010:    system("PAUSE");
011:    return 0;
012:  }


Se você pensou em 2.5, você pensou errado! O resultado é 2.0. Na linguagem C, a divisão entre dois inteiros, resulta em resultado inteiro, portando o resultado da divisão entre cinco e dois, é dois.
Se a sua intensão é apresentar o resultado real da divisão então, ao menos um dos operados deverá ser de ponto flutuante. Para isso recorro a utilização do cast que faz a conversão momentânea do dado.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    int a = 5, b = 2;
007:    float c;
008:    c = (float)a/b;
009:    printf("O resultado da divisao e: %f", c);
010:    system("PAUSE");
011:    return 0;
012:  }


Você pode ver a utilização do cast (float) na linha 8. Isso transforma o dado da variável a em float então este dado é dividido por 2. O resultado dessa operação é o 2.5.
Em resumo, os operadores aritméticos são tranqüilos de usar. O cuidado maior está sempre na divisão.

sexta-feira, 22 de fevereiro de 2008

lendo dados - a função scanf

Agora que você sabe como funciona o operador de endereço &, posso apresentar a você a função scanf (leia-se scanEFE).
Essa função, como a printf, está localizada na biblioteca stdio.h e serve como entrada de dados em seu programa. Tudo aquilo que você digita no teclado será lido por essa função.
É claro que para o scanf você deverá informar duas coisas:
  1. Em qual formato o dado será lido?
  2. Onde ele será armazenado?

Para informar o formato do dado para o scanf é necessário recorrer a tabela abaixo:
CódigoFormatação
%cLê um caractere
%dLê um inteiro positivo ou negativo (base decimal)
%iLê um inteiro positivo ou negativo (base decimal)
%eLê um número de ponto flutuante em notação científica
%fLê um número de ponto flutuante
%gLê um número de ponto flutuante podendo ser expressa em notação científica
%oLê um número em octal
%sLê uma cadeia de caracteres (string)
%uLê um inteiro sem sinal
%xLê um número hexadecimal
%nRecebe um valor inteiro correspondente ao número de caracteres lidos até então
%[]Busca por um conjunto de caracteres

A resposta genérica para a segunda pergunta é a memória. Devemos especificar para o scanf qual o endereço de memória ele deve guardar o dado inserido. Para essa operação utiliza-se o operador de endereço &.
A forma geral do scanf é:


scanf("código de formatação", lista de endereços);


Para ler duas variáveis, sexo e anoNascimento podemos fazer como no programa abaixo.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo;
007:    int anoNascimento;
008:    printf("Digite o sexo\n[F] - Feminino\n[M] - Masculino\n");
009:    scanf("%c",&sexo);
010:    printf("Digite o ano de nascimento: ");
011:    scanf("%d",&anoNascimento);
012:    system("PAUSE");
013:    return 0;
014:  }


Note que nas linhas 9 e 11 o código de formatação indica somente o tipo de dado a ser lido.
O scanf permite ler mais de uma variável na mesma instrução. Adaptando o programa acima para ler em apenas uma instrução fica da seguinte forma:


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo;
007:    int anoNascimento;
008:    printf("Digite o sexo\n[F] - Feminino\n[M] - Masculino\nEm seguida digite o ano de nascimento.");
009:    scanf("%c%d",&sexo, &anoNascimento);
010:    system("PAUSE");
011:    return 0;
012:  }


Particularmente não gosto dessa segunda opção porque não permite a limpeza do buffer do teclado entre uma leitura e outra. A limpeza é importante pois garante que nenhuma sujeira presente no buffer contaminará suas variáveis.
Para fazer a limpeza do buffer basta inserir a instrução


fflush(stdin);


antes de cada scanf.
Veja o primeiro programa escrito de uma forma mais segura.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo;
007:    int anoNascimento;
008:    printf("Digite o sexo\n[F] - Feminino\n[M] - Masculino\n");
009:    fflush(stdin);
010:    scanf("%c",&sexo);
011:    printf("Digite o ano de nascimento: ");
012:    fflush(stdin);
013:    scanf("%d",&anoNascimento);
014:    system("PAUSE");
015:    return 0;
016:  }


Agora sim, ler dados ficou ainda mais fácil!

quinta-feira, 21 de fevereiro de 2008

Operador de endereço

Quando falei sobre criação e inicialização de variáveis, falei também que cada variável recebe uma casa, chamada de memória.
Como toda casa possui um endereço (Rua, número, bairro, cidade, estado, país, CEP), a memória possui um endereçamento, muito mais simplificado, composto por números.
Esses números indexam a memória byte-a-byte.
Vamos recorrer ao exemplo abaixo para compreender melhor:

Endereço204820492050
IdentificadorsexoanoNascimento
Valor'F'1982

O exemplo representa um fragmento de memória, na qual estão presentes duas variáveis identificadas por sexo e anoNascimento. Pelo número de bytes alocados para cada variável e, com o auxílio da tabela de limites mínimos de variáveis, pode-se concluir que sexo é do tipo char e anoNascimento é inteiro.
Quando pergunto qual o endereço de sexo, a resposta deve ser 2048. Quando pergunto qual o endereço de anoNascimento, a dúvida impera!
Alguns respondem 2049, outros 2050, um grupo isolado arrisca 2049 e 2050. A resposta correta é 2049. O endereço de uma variável que ocupa mais de um byte é o menor endereço do bloco de memória ocupado pela variável. O bloco ocupado por anoNascimento é 2049-2050, portanto o menor endereço desse bloco é 2049.
Na linguagem C a forma utilizada para descobrir o endereço de uma variável é por meio do operador &.
O programa abaixo ilustra como se utiliza o operador & para imprimir na tela o endereço de uma variável.


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    char sexo = 'F';
007:    int anoNascimento = 1982;
008:
009:    printf("O endereco de sexo e %p\n", &sexo);
010:    printf("O endereco de anoNascimento e %p\n", &anoNascimento);
011:    system("PAUSE");
012:    return 0;
013:  }


Com base no fragmento de memória apresentado anteriormente, a saída esperada para esse programa é:


O endereço de sexo e 2048
O endereço de anoNascimento e 2049


Você deve estar se perguntando... Quando usarei esse operador?
Primeiramente na função scanf, utilizada na leitura de dados do teclado, e mais a frente em passagem de parâmetros por referência (o que é feito na função scanf) e no uso de ponteiros.
A propósito, a passagem de parâmetro por referência é feita utilizando ponteiros. :D

segunda-feira, 18 de fevereiro de 2008

A função printf()

No post Meu primeiro programa em C, apresentei o uso da função printf em sua forma mais ordinária. Aquela em que a utilizamos para apresentar mensagens fixas, como a apresentada abaixo.


printf("Uma mensagem para voce!");


Nessa forma não existem códigos de formatação.
Os códigos mais básicos servem para controlar tabulações, quebras de linhas, impressão de aspas, etc..., e são iniciados pela barra invertida seguida de um caractere.
A tabela abaixo apresenta esses códigos.

CódigoSignificado
\nQuebra de linha (Pula para a próxima linha)
\rRetrocede o cursor para o início da linha
\tInsere uma tabulação no texto
\bRetrocede o cursor uma posição
\"Imprime a aspas
\\Imprime uma barra invertida

Existem códigos de formatação para a impressão de variáveis. Não seria ótimo apresentar um número no meio de uma mensagem, por exemplo:


O numero 2 e par.


O programa que gera essa saída pode ser dado por:


001:  #include <stdio.h>
002:  #include <stdlib.h>
003:
004:  int main(int argc, char *argv[])
005:  {
006:    int num = 2;
007:
008:    printf("O numero %d e par\n", num);
009:    system("PAUSE");
010:    return 0;
011:  }


Esse raciocínio é válido para todos os tipos de dados. A tabela abaixo apresenta o código de formatação e o formato impresso:

CódigoFormatação
%cCaractere
%dinteiros com sinais (base decimal)
%iinteiros com sinais (base decimal)
%eNotação científica (e minúsculo)
%Enotação científica (E maiúsculo)
%fponto flutuante
%gusa %f ou %e, o que for mais curto graficamente
%Gusa %f ou %E, o que for mais curto graficamente
%oimprime um número em base octal
%scadeia de caracteres (string)
%uinteiros sem sinal
%ximprime um número na base hexadecimal. As letras serão minúsculas.
%Ximprime um número na base hexadecimal. As letras serão maiúsculas.
%pApresenta endereço de memória.

Se você é um pouco perspicaz estará se perguntando como fazer para imprimir o sinal de %. Isso é fácil, basta duplicar o sinal de percentual (%%) no printf.
Se você acha que acabou, aguarde o post sobre a formatação de precisão e campos utilizando o printf.

Identificadores

O nome que damos a uma função ou variável é chamado de identificador.
Os identificadores são fundamentais na compreensão do programa. Para isso devemos escolher identificadores significativos, que indiquem exatamente o papel que a função ou variável desempenha no sistema.
Uma variável que armazena, por exemplo, o peso de um paciente pode ser identificada por pesoPaciente. Lendo somente o identificador podemos deduzir o que essa variável faz.
Procure resistir à tentação de criar identificadores engraçados ou sem significado. Eles prejudicam a leitura do programa e, conseqüentemente, aumentam o tempo de manutenção.
Para funções, é interessante demonstrar que ela executa uma ação. Uma função que calcula o imposto de renda sobre um rendimento qualquer poderá ser identificada como calcularImpostoDeRenda. Note que a primeira palavra é um verbo que se apresenta no infinitivo. Essa característica reforça a execução de uma ação pela função (calcular). As demais palavras indicam qual o objetivo da ação (imposto de renda). Os objetos da ação serão tratados como parâmetros da função. Se você não sabe o que é uma função, acalme-se, em breve eu a apresentarei a você.
A linguagem C exige uma regra para a criação de identificadores. Ela é muito simples, mas ainda é uma regra....
O primeiro caractere deve ser letra ou sinal de sublinha ( _ ). Os demais caracteres podem ser letras, números ou sinal de sublinha, portanto, identificadores como 1peso ou @email estão errados.
Algumas coisas que você deve lembrar:
Os identificadores não devem coincidir com palavras reservadas da linguagem, portanto se você gosta da palavra switch, lamento decepcioná-lo, mas ela é uma palavra reservada.
A linguagem C distingue letras maiúsculas de minúsculas, ou seja ela é sensível ao caso. Essa característica implica em uma variável pesoPaciente diferente de PesoPaciente.
Agora a criação de identificadores é uma tarefa mais fácil.

sexta-feira, 15 de fevereiro de 2008

Criação e inicialização de variáveis

Na linguagem C a criação de variáveis é bastante simples. O comando de criação é formado pelo tipo de dados seguido de uma ou mais variáveis que assumirão aquele tipo e termina-se o comando com o famoso ponto-e-vírgula.
Ex.: Para criar uma variável do tipo char podemos fazer:


char opcao;


Por esse comando sabemos que existe no programa uma variável chamada opção que manipula dados do tipo char.
Para declarar uma lista de variáveis utilizamos o tipo de dado seguido dos identificadores das variáveis separados por vírgula e, finalmente, o término do comando dado pelo ponto-e-vírgula.
Ex.: Para criar uma lista de variáveis do tipo float podemos fazer:


float proventos, despesas, saldo;


Com base na linha anterior, podemos constatar que no programa existirão três variáveis de ponto flutuante que armazenarão valores relativos a proventos (dinheiro que entra em seu fluxo de caixa, tal como salário), despesas (aquilo que você gasta) e saldo (diferença entre proventos e despesas).
Agora que você sabe como criar variáveis vamos a inicialização delas. Vou contar uma estória triste. Quando uma variável nasce, ela recebe uma casa (chamada de memória) suja. A sujeira na casa da variável é representada por um valor aleatório e que, se não for limpa, poderá ser a causa de grandes problemas para o seu programa. Casa limpa é sinônimo da saúde.
A inicialização pode ocorrer no momento da criação da variável, por exemplo:


float proventos=0, despesas=0, saldo=0;


Isso indica que as três variáveis declaradas anteriormente são iniciadas com o valor 0. Agora sei que nelas existe um valor conhecido e não sujeira de memória.
Duas perguntas são freqüentes nesse tema:

  • Sou obrigado a inicializar uma variável?
A resposta é não. Se a variável, por exemplo, receberá um valor de uma leitura de dados ela não necessita de inicialização.
A inicialização é obrigatória quando a variável é utilizada para auto-alteração (auto-incremento, auto-decremento, auto-multiplicação, auto-etc...).

  • O valor a ser utilizado na inicialização é sempre zero?
A resposta é não. Imagine uma variável multiplicadora (auto-multiplicadora) que acumula o seu valor anterior e multiplica-o por um valor qualquer, por exemplo:


multiplicadora = multiplicadora * fatorCorrecao;
multiplicadora = multiplicadora * juros;


Se multiplicadora for inicializado com 0, o resultado final dessa operação será sempre 0. Então multiplicadora deverá ser inicializada com um número neutro no contexto da multiplicação. O valor que procuramos é o 1. Eu sempre digo que o valor inicial de uma variável depende do seu uso futuro.
Espero que tenha compreendido que declarar uma variável é mais do que escrever uma simples linha de código.

Tipos básicos de dados na linguagem C.

Os tipos de dados são utilizados para assinalar qual será a forma de tratamento dispensada ao dado em memória ou outro sistema de armazenamento de dados.
A linguagem C possui cinco tipos básicos de dados:
  1. char
  2. int
  3. float
  4. double
  5. void

Com exceção do void, os tipos em linguagem C são todos numéricos e podem ser aplicadas às operações aritméticas disponíveis no C, com ressalvas ao operador de módulo.
O tipo void é utilizado como retorno de funções e tipo de ponteiros.
Os tipos char e int são utilizados para armazenar números inteiros negativos e positivos. O tipo int utiliza mais bytes para armazenamento que o char, o que lhe proporciona maior faixa de valores.
Os tipos float e doube armazenam números de ponto flutuante (números reais). O double utiliza maior número de bytes que o float, o que proporciona maior faixa de valores e ainda, maior precisão numérica.
A American National Standard Institute (ANSI) padroniza os valores mínimos para os tipos de dados do C. O compilador que você utiliza deve seguir esse padrão!
Abaixo está a tabela de tipos com seus respectivos tamanhos e faixa de valores padronizada pela ANSI.

TipoTamanho (*)Faixa mínima
char1-127 a 127
int2-32.767 a 32.767
float4Seis dígitos de precisão
double8Dez dígitos de precisão
void--
* Valor aproximado em bytes.

quinta-feira, 14 de fevereiro de 2008

Anatomia do programa em C.

No tópico "C - Meu primeiro programa!" apresentei um programa simples que dizia "Estou vivo....!" para quem mexia com ele!
Vamos entender o seu funcionamento.



001:  #include <stdio.h>
002:
003:  int main(int argc, char *argv[])
004:  {
005:    printf("Estou vivo....!");
006:    return 0;
007:  }



Quando você executa um programa no sistema operacional, dentre aquele amontoado de código de máquina, existe um especial, que indica onde o sistema operacional deverá iniciar a execução do programa.
A linguagem C marca esse ponto com a função main, a qual pode ser vista na linha 3. A palavra reservada int que precede o main é o tipo de retorno da função. Isso indica que o main deverá retornar um valor inteiro. Veja na linha 6 o que está acontecendo... O main retorna para o sistema operacional o valor 0 por meio da palavra reservada return.
Voltando a linha 3, após o main, estão presentes os argumentos da função. Esses argumentos aparecem entre parênteses e são separados por vírgulas. Existirá um momento oportuno onde mostrarei como esses argumentos podem ser explorados.
Na linha 4, é aberta uma chave que marca o início da função main. Na linha 7 a chave que fecha, marca o fim da função.
Na realidade as chaves marcam um bloco de comandos, nesse caso um bloco de comandos
da função main, e elas existirão aos montes em seus programas. Acostume-se a elas e lembre-se que para cada chave aberta deverá existir uma fechada.
A única linha que faz algo realmente sensível é a 5, a qual contém a chamada a função printf. Veja que o argumento da função printf "Estou vivo....!" é o que vemos quando executamos o programa. Altere o argumento para "Estou corrompendo o seu sistema de arquivos...", compile e execute o programa novamente. Pode executar... Será muito, muito divertido!
O que aconteceu? Seu sistema foi corrompido? Não! Claro que não! Você está produzindo somente mensagens que o programa fornece ao usuário.
A função printf faz parde da biblioteca stdio.h. stdio vem de standard input/output e é nessa biblioteca que estão declaradas as funções de entrada e saída padrões do C. Para ter acesso a a elas, utilizamos a diretiva #include apresentada na linha 1.
Acho que estendemos demais nesse tópico. Para finalizá-lo você é capaz de responder as seguintes perguntas?

1. Qual o comando que exibe mensagens aos usuários?
2. Em qual biblioteca estão localizadas as funções de entrada de dados?
3. O que pode significar função main (main function)?
4. Quando você usará os argumentos da função main?
5. A função main retorna sempre zero?
6. A mensagem que um programa fornece reflete fielmente o que está sendo executado por ele?

quarta-feira, 13 de fevereiro de 2008

C - Meu primeiro programa!

O primeiro programa em C é como o seu primeiro sutien. Você nunca esquece!
Nunca tive um sutien, mas, bem.... O meu primeiro programa em C não esqueci e portanto,você não deverá esquecer o seu!
Vamos a ele!


001:  #include <stdio.h>
002:
003:  int main(int argc, char *argv[])
004:  {
005:    printf("Estou vivo....!");
006:    return 0;
007:  }


O resultado da execução desse programa é apresentado abaixo:
Estou vivo....!
Viu como é simples!
Sei que parte desse código pode parecer grego. Para entendê-lo melhor é necessário dissecá-lo.Em breve veremos a anatomia de um programa em C.