Mostrando postagens com marcador comandos de repetição. Mostrar todas as postagens
Mostrando postagens com marcador comandos de repetição. Mostrar todas as postagens

quinta-feira, 12 de novembro de 2009

De novo! De novo!... Final (curiosidades)

Para encerrar nossa série sobre os comandos de repetição, hoje vamos conhecer algumas 'curiosidades' sobre eles.

Tá faltando alguma coisa aí?
Acredito que você deve ter reparado no comando de repetição for, onde os comandos de controle de repetição do bloco ficam dentro de () separados por ;. Pois bem, você sabia que é possível usar um for sem que todas as suas partes estejam preenchidas? Lembra do exemplo que utilizamos para exemplificar o uso de um FLAG para sair de uma repetição (aqui)? Vamos refazer este exemplo, só que agora, utilizando o comando de repetição for, e você entenderá melhor como isto é possível.


//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);
 for( ;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");
}


O código deste exemplo é praticamente o mesmo que vimos antes, a única alteração está na linha 11, onde vemos o for.
Observe que não existe a inicialização de uma variável contadora, já que não temos um número de repetições determinado. Observe, também, que não existe um incremento.
Temos somente o comando que avalia se o bloco de comandos será repetido ou não.
Pode compilar e executar este código. Você verá que ele faz, exatamente, a mesma coisa que a versão utilizando o comando de repetição while.
Agora, vamos ir um pouco mais longe. Temos um comando dentro dos () do comando for. Poderíamos não ter nenhum?
Resposta: SIM. Um for sem nenhum comando dentro dos seus () cria o que se chama de loop infinito.
Por quê? Por quê? Por quê?
Já ouviu falar na Lei da Inércia? O loop infinito é basicamente isto. Se não dissermos ao comando for quando ele deve parar, ele vai continuar repetindo o bloco 'eternamente'.
E qual a utilidade disto??? Vamos a outro exemplo:


//EXEMPLO DE UTILIZAÇAO DE UM LOOP INFINITO
#include <stdio.h>
#include <stdlib.h>
 
int main(){
 int opcao, num, dobro, quadrado;
 
 for(;;){
    printf("Selecione uma das opcoes abaixo:\n");
    printf("1. Calcular o dobro de um numero\n");
    printf("2. Calcular o quadrado de um numero\n");
    printf("3. Encerrar o programa\n");
    printf("\nOpcao: ");
    scanf("%d",&opcao);
    system("cls");
    if (opcao == 1){
       printf("Digite um numero inteiro: ");
       scanf("%d",&num);
       printf("O dobro de %d eh %d.\n",num, num*2);
       system("pause");
       system("cls");
    }
    else
       if (opcao == 2){
          printf("Digite um numero inteiro: ");
          scanf("%d",&num);
          printf("O quadrado de %d eh %d.\n",num, num*num);
          system("pause");
          system("cls");
       }
       else
          if (opcao == 3){
             printf("\nO programa sera encerrado.\nObrigado por utilizar nossos sistemas!\n");
             system("pause");
             break;
          }
          else {
             printf("\nOPCAO INVALIDA!!! Tente novamente.\n");
             system("pause");
          }
    system("cls");
 }
}


Olhe bem para este código. Acredito que ele seja 'familiar' para você. Se não é, dê uma olhada aqui. Se você compilar e executar este código acima, verá que ele faz a mesma coisa que o exemplo que vimos para o comando de repetição do while.
Mas podemos notar várias diferenças entre eles, certo?
A 1a delas é que este não utiliza um do while, e sim, um loop infinito, utilizando um for 'sem comandos'.
A 2a é que este não utiliza um comando de decisão switch, e sim, vários comandos de decisão ifs aninhados.
Pergunta: Por que não usar o switch já que é muito mais prático?
A resposta para isto está na linha 35. É o comando break. O comando switch faz uso do comando break para sair do bloco de decisão depois que são executados os comandos referentes a uma única escolha. Só que neste caso, o comando break é usado para encerrar o loop infinito, e permitir o término do programa. Se tivéssemos usado o switch, o break nunca seria associado ao for do loop infinito, e sim, ao switch.
Olhando para este código, podemos ver porque o comando do while foi criado (rsrs).
Vamos a uma última 'curiosidade' (pelo menos por hoje).

Tem coisa demais aí?
Se por um lado, podemos não ter comando nenhum dentro dos () de um for; por outro, podemos ter mais de um comando entre os ; dentro dos () do for.
Antes de vermos o código de exemplo, vamos imaginar a seguinte situação:
Uma dupla está numa competição onde uma das provas consiste em encher um recipiente A de 3 litros com um líquido contido num recipiente B de 4,25 litros, percorrendo um circuito e utilizando dois outros recipientes menores de 500ml e 350ml, um para cada competidor da dupla respectivamente. Cada vez em que o líquido é levado do recipiente B para o A, é contada uma volta no circuito. A dupla tem que encher o recipiente A em no máximo 5 voltas. Os dois competidores podem levar o líquido do recipiente B para o A usando o seu respectivo recipiente na mesma volta. Devido as dificuldades no circuito, nem sempre os recipientes menores chegarão cheios ao recipiente A. Se algum dos competidores tentar fraudar a prova, informando um valor maior do que o seu recipiente pode transportar, o valor informado será ignorado. Como fazer um programa que controle isto???
Este é o nosso exemplo. Vamos a ele.


//PROGRAMA DE CONTROLE DA EXECUÇÃO DE UMA PROVA DE UMA COMPETIÇÃO
#include <stdio.h>
#include <stdlib.h>
 
int main(){
 int voltas;
 float liqA, total = 3000, rec500, rec350;
 
 for(voltas = 0, liqA = 0, rec500 = 0, rec350 = 0; liqA < total && voltas < 5; voltas++){
    printf("VOLTA %d:\n",voltas + 1);
    printf("Digite a quantidade em ml de liquido no recipiente de 500ml: ");
    scanf("%f",&rec500);
    if (rec500 <= 500)
       liqA += rec500;
    rec500 = 0;
    printf("Digite a quantidade em ml de liquido no recipiente de 350ml: ");
    scanf("%f",&rec350);
    if (rec350 <= 350)
       liqA += rec350;
    rec350 = 0;
    printf("\n");
 }
 if (liqA >= total)
    printf("\nA dupla cumpriu a tarefa em %d voltas e ganhou os pontos da prova.\n", voltas);
 else
    printf("\nA dupla so conseguiu transportar %.2f ml e nao ganhou os pontos da prova.\n", liqA);
 system ("pause");
}


Alguma dificuldade em entender este código?
Calma, vou explicar alguns detalhes dele.
Primeiro definimos as nossas variáveis. Com os nomes que demos a elas, não é difícil saber qual a função de cada uma delas.
Depois disto, dentro do nosso for, inicializamos todas que ainda não haviam sido inicializadas. Observe que para separar os vários comandos de inicialização de variáveis utilizamos a , (vírgula).
Depois definimos a condição para que o nosso for executasse a repetição do bloco de comandos, no caso, enquanto o líquido no recipiente A fosse menor que a volume desejado, e enquanto não tivessem acabado as 5 voltas.
No bloco de comandos do for, estão os comandos para receber os valores transportados e acumular no recipiente A. Os ifs asseguram que os valores de cada recipiente estão corretos, evitando uma possível fraude, já que só acumulam se eles estiverem corretos.
Os comandos após o for são para informar se a dupla conseguiu ou não completar a prova.
Viu como fica fácil depois que se sabe!!!
Até a próxima.

terça-feira, 10 de novembro de 2009

De novo! De novo!... Parte III (do while)

Vamos prosseguir nossa série sobre comandos de repetição. Hoje veremos o comando de repetição do while.

Faça primeiro. Avalie depois!
Existe um dito popular que fala que se deve pensar duas vezes antes de falar. Mas existem ocasiões em que é necessário executar algumas operações antes e avaliar o resultado delas depois. O exemplo mais clássico disto são as listas de opções ou menu (faça biquinho para pronunciar corretamente rsrs).
Nos comandos de repetição while e for, a avaliação é feita antes da 1a execução do bloco de comandos; já no comando de repetição do while, esta avaliação é feita depois que o bloco de comandos é executado a 1a vez, ou seja, pelo menos uma vez o bloco de comandos será executado.
A sintaxe do comando de repetição do while é esta:
 do {
    .
    .
    .
    } while (condição);


Como de costume, vamos a um código para exemplificar o uso do comando de repetição do while.


//EXEMPLO DE UTILIZAÇAO DO COMANDO DE REPETIÇÃO DO WHILE
#include <stdio.h>
#include <stdlib.h>
 
int main(){
 int opcao, num, dobro, quadrado;
 
 do {
    printf("Selecione uma das opcoes abaixo:\n");
    printf("1. Calcular o dobro de um numero\n");
    printf("2. Calcular o quadrado de um numero\n");
    printf("3. Encerrar o programa\n");
    printf("\nOpcao: ");
    scanf("%d",&opcao);
    system("cls");
    switch (opcao){
       case 1:
          printf("Digite um numero inteiro: ");
          scanf("%d",&num);
          printf("O dobro de %d eh %d.\n",num, num*2);
          system("pause");
          system("cls");
          break;
       case 2:
          printf("Digite um numero inteiro: ");
          scanf("%d",&num);
          printf("O quadrado de %d eh %d.\n",num, num*num);
          system("pause");
          system("cls");
          break;
       case 3:
          printf("\nO programa sera encerrado.\nObrigado por utilizar nossos sistemas!\n");
          system("pause");
          break;
       default:
          printf("\nOPCAO INVALIDA!!! Tente novamente.\n");
          system("pause");
    }
    system("cls");
 }while (opcao != 3);
}


Observe que todos os comandos do programa estão dentro do bloco de comandos do comando de repetição do while, que começa na linha 8 e só acaba na linha 40. Nesta linha 40 está a avaliação da opção escolhida pelo usuário.
Primeiro, são apresentadas as opções disponíveis ao usuário, nas linhas de 9 a 12.
A linha 14 recebe a opção digitada pelo usuário, que é avaliada pelo comando de decisão switch da linha 16.
Enquanto a opção for diferente de 3 (sair), o bloco de comandos será executado.
Os outros comandos dentro do bloco de comandos do comando de decisão switch são para realizar a operação escolhida, apresentar o resultado desta operação, e ainda, permitir que o usuário repita sua escolha se fizer uma escolha inválida.
Fácil, não é?

Até a próxima.

sábado, 7 de novembro de 2009

De novo! De novo!... Parte II (while/contador/for)

Continuando nossa série sobre comandos de repetição, hoje veremos como repetir um bloco de comandos por um determinado número de vezes.

Faça isto todas essas vezes!
No post anterior, vimos como realizar a repetição de um bloco de comandos por um número indeterminado de vezes. Finalizando esta repetição quando um determinado valor fosse digitado (o famoso FLAG).
E quando sabemos exatamente quantas vezes queremos que um bloco seja repetido?
Imagine um programa que calcule a média aritmética de 15 valores inteiros digitados pelo usuário.
Já sabemos a quantidade de valores que serão digitados, neste caso, 15. Esta é a quantidade de vezes que devemos pedir ao usuário que digite um valor inteiro, ler este valor e somá-lo a um total para que, depois, possamos fazer a média dos valores digitados.
Vamos a um código para exemplificar isto.


//PROGRAMA QUE CALCULA A MÉDIA ARITMÉTICA ENTRE 15 VALORES INTEIROS
#include <stdio.h>
#include <stdlib.h>
 
const int MAXDIGIT=15;
int main(){
 int valor, total=0, contador;
 float media;
 
 contador=0;
 while (contador < MAXDIGIT){
    printf("Digite um valor inteiro positivo: ");
    scanf("%d",&valor);
    total += valor;
    contador++;
 }
 media = total / MAXDIGIT;
 printf("A media entre os %d valores digitados eh %.2f\n",MAXDIGIT, media);
 system ("pause");
}


Observe a utilização de uma constante inteira MAXDIGIT. Poderíamos usar diretamente o número 15, que é a quantidade de repetições que desejamos; no entanto, usar uma constante torna este código mais fácil de ser alterado. Se desejarmos mudar o valor de repetições de 15 para 10, por exemplo, só precisaríamos alterar a linha 5. Se tivéssemos usado o valor diretamente, teríamos que alterar as linhas 11, 17 e 18. Num código pequeno como este, isto não é tão vantajoso, mas imagine num código onde este valor aparecesse muitas outras vezes.
Dito isto, vamos ao que, no post de hoje, realmente nos interessa neste código: as linhas 10, 11 e 15.
Na linha 10 nós 'zeramos' uma variável inteira chamada contador. Esta variável poderia ter qualquer outro nome (o mais usado é i), mas escolhi este para deixar bem claro qual a função dela.
Para que o computador repita um bloco de comandos por um determinado número de vezes, ele deve saber quantas vezes este bloco já foi repetido para, assim, saber quando deve parar de repetí-lo. Por isto, o uso desta variável, que é chamada de variável contadora ou contador.
Na linha 15 esta variável é incrementada, depois que os comandos do bloco foram executados; ou seja, seria como se ele 'dissesse': fiz outra vez.
Na linha 11 é feita a verificação de quantas vezes a repetição já foi realizada. Se ainda não chegou ao número de vezes desejado, o bloco será repetido. Uma vez atingido o número de repetições desejado, o bloco é 'pulado' e o comando seguinte a ele é executado, neste caso, a linha 17 que calcula a média dos valores digitados.
A sintaxe do comando de repetição while com um número de repetições determinado é esta:

 contador = 0;
 while (contador < Número de repetições desejado){
    .
    .
    .
    contador++;
}


Existe uma outra forma de executar esta repetição no C. Utilizando um comando de repetição específico para uso com número de repetições determinado: o for.
A sintaxe do comando de repetições for é esta:

 for(contador = 0; contador < Número de repetições desejado; contador++){
    .
    .
    .
 }


Percebeu alguma coisa em comum com a sintaxe do comando de repetição while com um número de repetições determinado? Outra coisa que deve ser observada, são os ; dentro dos (). Eles indicam o fim de cada comando de controle da repetição.
Observe o mesmo código do exemplo anterior usando o comando de repetição for.


//PROGRAMA QUE CALCULA A MÉDIA ARITMÉTICA ENTRE 15 VALORES INTEIROS
#include <stdio.h>
#include <stdlib.h>
 
const int MAXDIGIT=15;
int main(){
 int valor, total=0, contador;
 float media;
 
 for(contador = 0; contador < MAXDIGIT; contador++){
    printf("Digite um valor inteiro positivo: ");
    scanf("%d",&valor);
    total += valor;
 }
 media = total / MAXDIGIT;
 printf("A media entre os %d valores digitados eh %.2f\n",MAXDIGIT, media);
 system ("pause");
}


Qual dos dois usar? Você decide! Uma grande maioria de programadores profissionais prefere esta 2ª versão, que utiliza o for.

Por hoje é só pessoal. Até a próxima.

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.