quinta-feira, 5 de novembro de 2009

De novo! De novo!... Parte I (while/flag)

Hoje vamos começar a entender como funcionam os comandos de repetição.

Como fazer para que uma operação seja repetida?
Até agora vimos programas simples, em que são necessárias poucas interações do usuário. Pedimos que ele digite 2 ou 3 valores no máximo e, para isto, usamos um printf para informar o que ele deve digitar a cada vez. E se precisarmos que o usuário digite 30 valores? Já imaginou o tamanho do código? Quantas vezes será necessário digitar o mesmo trecho do printf? Não tem como fazer com que o computador execute essa repetição por nós? A resposta é SIM.
Antes de entender como fazer isto no C, vamos entender o que é uma repetição.

Repetir? O quê? E até quando?
Repetição é a execução de uma operação, que já foi realizada, outra vez.
Imagine que você tenha que colocar objetos dentro de uma caixa. Os passos para isto seriam:

abrir a caixa;
verificar se existem objetos para colocar na caixa;
se existir, pegar um objeto;
colocar o objeto dentro da caixa;
verificar se existem objetos para colocar na caixa;
se existir, pegar um objeto;
colocar o objeto dentro da caixa;
verificar se existem objetos para colocar na caixa;
se existir, pegar um objeto;
10º colocar o objeto dentro da caixa;
11º verificar se existem objetos para colocar na caixa;
12º se não existir;
13º fechar a caixa;

Repare que os 5º, 8º e 11º passos são idênticos ao 2º passo, os 6º e 8º passos são idênticos ao 3º passo, e o 7º e o 10º passos são idênticos ao 4º passo. Isto significa que as operações dos 2º, 3º e 4º passos se repetem. Pensando em termos de código fonte, logo vemos que os 2º, 3º e 4º passos fazem parte de um bloco. Já identificamos o o quê. Falta o até quando?
Olhando este roteiro acima, vemos que o nosso bloco se repete enquanto tiver objetos para colocar na caixa. Quando acabarem os objetos a serem colocados na caixa, não é mais necessário executar o nosso bloco.
Pronto! É assim que devemos pensar quando falarmos de repetição.
Um bloco de comandos que será repetido enquanto uma condição for verdadeira.
Neste caso, o bloco são os 2º, 3º e 4º passos, e a condição é que ainda hajam objetos para serem colocados na caixa. Se houverem 20 objetos, o bloco será repetido por 20 vezes, se houverem 5 objetos, será repetido por 5 vezes.
O comando C para isto é o while, e segue esta estrutura:

 while (condição){
            bloco de comandos
 }

Vamos criar um código fonte para exemplificar isto. Neste código vamos pedir que o usuário digite alguns valores, e vamos somar os valores digitados e exibir a soma deles quanto o usuário finalizar a digitação. Fazendo uma analogia com os objetos e a caixa, os objetos são os valores digitados e colocar esses objetos na caixa seria o mesmo que somá-los. Até aí está tranquilo, mas como vamos saber que 'acabaram os objetos'?

Quando se acena a bandeira, acaba a corrida
Para que o computador saiba quando o usuário finalizou a digitação de valores, alguém tem que informar isto a ele. Normalmente, quem deve fazer isto é o próprio usuário. Mas como ele vai fazer isto?
Você já viu uma corrida profissional de carros? Vários carros ficam dando voltas e voltas em uma pista de corridas. Essas corridas tem uma duração definida por quantas voltas serão realizadas, mas algumas vezes por causa de acidentes que podem acontecer, a quantidade de voltas pode ser reduzida. Quem define esta redução são os comissários de prova. O piloto do carro não tem idéia de que a corrida irá acabar antes do que foi determinado anteriormente. Para informar ao piloto que a corrida acabou é acenada um bandeira quadriculada. Ao ver esta bandeira quadriculada, o piloto sabe que é o fim da corrida.
O C utiliza o mesmo artifício. A isto se dá o nome de FLAG, que significa bandeira em inglês, e funciona assim:
Escolhemos um valor que, se for digitado, indicará que se deseja finalizar a entrada, e informamos isto ao usuário.
Geralmente este valor será definido como uma constante, já que será único e não será alterado durante a execução do programa.
No nosso exemplo usaremos o valor 0 (zero), já que somar 0 a um valor resultará no próprio valor.
Vamos ao código.


//EXEMPLOS DE COMANDO DE REPETIÇÃO (FLAG)
#include <stdio.h>
#include <stdlib.h>
 
const int SAIR=0;
int main(){
 int num, total=0;
 
 while (num != SAIR){
    printf("Digite um numero inteiro (0 (zero) para sair): ");
    scanf("%d",num);
    total += num;
 }
 printf("A soma dos valores informados eh igual a %d\n", total);
 system("pause");
}


Antes que você tente compilar este código, que parece estar correto, eu gostaria de informar que existe um erro grave nele. Sabe qual é?
Observe a linha 9. Nela está o nosso comando de repetição while e a condição que controlará a repetição, no caso enquanto o valor digitado for diferente do valor da constante inteira SAIR que é 0.
Como ainda não foi digitado nenhum valor, não se sabe qual o valor da variável num. Outra coisa a observar, é que se o usuário digitar 0, que é o valor da constante SAIR, a soma da linha 12 será executada, quando não deveria ser. Como escolhemos o valor 0 para ser o FLAG, esta soma não afetará o resultado final; mas se tivéssemos escolhido o valor -99, por exemplo, o resultado final estaria totalmente comprometido.
Sendo assim, temos que avaliar o valor digitado antes de efetuar a repetição.
Vejamos como ficaria este código, com esta avaliação antes da repetição, que é a forma correta.


//EXEMPLOS DE COMANDO DE REPETIÇÃO (FLAG)
#include <stdio.h>
#include <stdlib.h>
 
const int SAIR=0;
int main(){
 int num, total=0;
 
 printf("Digite um numero inteiro (0 (zero) para sair): ");
 scanf("%d",num);
 while (num != SAIR){
    total += num;
    printf("Digite um numero inteiro (0 (zero) para sair): ");
    scanf("%d",num);
 }
 printf("A soma dos valores informados eh igual a %d\n", total);
 system("pause");
}


Agora sim.
O valor digitado será armazenado na variável num (linha 10) antes de ser avaliado pelo comando de repetição while.
Se o usuário tiver digitado 0 que é o valor do FLAG, os comandos do bloco não serão repetidos.
Pode compilar e executar este código. Faça os seus testes, altere o valor do FLAG e verifique o que acontece.
É mais fácil do que parece.

E se quisermos repetir um bloco de comandos por um determinado número de vezes?
Veremos isto no próximo post.

3 comentários:

  1. ainde temos um erro neste comando amigo, pois ele está sem o & no scanf das linhas 10 e 14. MUito bom o blog e parabens pela iniciativa.

    Att, Vinicius Nascimento
    twitter: @JoseVinnycius
    msn: j_vinicius_ns@hotmail.com
    Orkut: http://www.orkut.com.br/Main#Profile?uid=12201242178651381807
    facebook: http://www.facebook.com/home.php#!/profile.php?id=100000014452630

    ResponderExcluir
  2. então o flag ñ é um comando q nem o while por exemplo e sim um tipo de ação, tipo, a finalidade do flag é encerrar uma repetição usando outros comandos, como nesse caso, o while, né isso?

    ResponderExcluir
  3. Flag é uma sinalização apenas, normalmente utilizado em lógica binário, e neste exemplo (des)ativa o laço

    ResponderExcluir