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.