PRÁTICA - ESTRUTURAS DE CONTROLE NA LINGUAGEM C

 

 

 

Como se sabe, controlar o fluxo do programa é mais do que uma necessidade para os programadores, mas agora você irá estudar isso na prática. Mas antes veja um detalhe importante.

 

Em "C" os comandos são divididos em blocos onde se abrem e fecham esses blocos com chaves.

 
 

Veja o exemplo a seguir:

 
/*
  SÍNTESE
    Objetivo: Somar duas variáveis. 
    Entrada: Nenhuma.
    Saída: Resultado da soma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{ /*essa chave inicia o bloco do programa principal*/
     printf("Os programas em C são divididos em blocos.");
     getch();
} //essa chave fecha o bloco do programa principal
 

Nesse exemplo em particular só tivemos um bloco que foi a função principal, mas nos nossos próximos exemplos você vai começar a observar mais blocos em um único programa.

 

Agora que você já tem uma noção superficial de blocos vamos iniciar nossos estudos práticos em estruturas de controle, onde voltaremos a tocar no assunto de blocos.

 
ESTRUTURA SEQUÊNCIAL
 

Para refrescar sua memória, estrutura sequencial corresponde a um conjunto de ações que serão executadas sequencialmente linha após linha, ou seja, assim como se escreve, de cima para baixo e da esquerda para direita.

 

Por exemplo: Um universitário necessita de passar por várias etapas para conseguir entrar na faculdade, ou seja, teve que respeitar uma sequência de estudos para conseguir alcançar seu objetivo.

 
 
algoritmo calculaMedia;
//Síntese
     //Objetivo: Calcular a média de duas notas
     //Entrada: duas notas
     //Saída: media aritmética das duas notas

  principal
//Declarações
      real nota_1, nota_2, media;
//Instruções
  
     escreva("Informe a primeira nota:");
     leia(nota_1);
     escreva("Informe a segunda nota:");
     leia (nota_2);
     media = (nota_1 + nota_2) / 2;
     escreva("Média final:", media);
fimPrincipal
 

A implementação deste algoritmo em linguagem "C" seria:

 
/*
  SÍNTESE
    Objetivo: Somar duas variáveis. 
    Entrada: Nenhuma.
    Saída: Resultado da soma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{    
    //Declarações
       float nota_1, nota_2, media;
    //Início
       printf("\nInforme a primeira nota: ");
       scanf("%f",&nota_1);    //lendo a primeira nota
       printf("\nInforme a segunda nota: ");
       scanf("%f",&nota_2);    //lendo a segunda nota
       media=(nota_1+nota_2)/2;  //o cálculo da média
       printf("\nMedia final: %.2f",media);  // mostrando a média
       getch();
} //Fim
 
 

Como você pôde observar a execução desse programa não teve nenhuma variação do seu fluxo. Vamos ver agora uma nova instrução, que efetua a alteração sequencial de execução de um programa.

 
ESTRUTURAS DE SELEÇÃO
 

As estruturas de seleção permitem a execução de uma instrução ou um bloco de instruçães escolhidas após a avaliação do resultado de um teste condicional que pode ser VERDADEIRO ou FALSO.

 
 

Este teste condicional pode consistir em uma operação relacional simples ou em uma expressão mais complexa. Existem algumas características importantes relacionadas as estruturas de seleção, permitindo que elas sejam dividas ou classificadas em: simples, composta, aninhada e de múltipla escolha.

 
Simples:
 

Nesse tipo de seleção antes de executar um bloco de instruções, o programa testa a condição. lembre-se só executará o bloco se o resultado da condição for VERDADEIRO. Toda instrução de seleção resulta em uma informação lógica (VERDADEIRO ou FALSO) que distinguirá o caminho a ser seguido pelo programa, quebrando a sua ordem sempre sequencial.

 

Observe o exemplo anterior que apresenta como resultado a média conseguida por um aluno que obteve as notas anteriores de 7.5 e 9.5. Supondo que a média mínima para aprovação seja 7.0 em uma escola, pode-se incluir na apresentação final a mensagem que identifica a situação deste aluno, que será APROVADO ou REPROVADO, de acordo com a média alcançada. Sendo assim, será necessária a inclusão de um teste condicional que possibilite a correta identificação da situação do aluno. Como estudado na parte lógica desta disciplina será necessária a inclusão do comando SE...ENTÃO, que resultará no algoritmo:

 
algoritmo mediaAritmerica;
//Síntese
     //Objetivo: Calcular a media aritmética de duas  notas e informar 
                somente a aprovação para média maior que 7.0.
     //Entrada: Duas notas
     //Saída: media aritmética das duas notas

principal  
    //Declarações  
      real nota_1, nota_2, media;
  
  //Instruçoes  
     escreva("Informe a primeira nota:");
     leia(nota_1);
     escreva("Informe a segunda nota:");
     leia (nota_2);
     media = (nota_1 + nota_2) / 2;
     escreva("Média final:", media);
     se (media >= 7) entao
       escreva("Aluno aprovado");
     fimSe  
fimPrincipal
 

Após identificada a lógica que resolve o problema apresentado e o desenvolvimento do seu respectivo algoritmo, será iniciada a elaboração do programa que consiste na tradução do algoritmo proposto.

 
/*
  SÍNTESE
    Objetivo: Calcular a media aritmética de duas  notas e informar 
              somente a aprovação para média maior ou igual a 7.0. 
    Entrada: Duas notas.
    Saída: Média final e a situação.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{    
    //Declarações
       float nota_1, nota_2, media;
    //Início
       printf("\nInforme a primeira nota: ");
       scanf("%f",&nota_1);    //lendo a primeira nota
       printf("\nInforme a segunda nota: ");
       scanf("%f",&nota_2);    //lendo a segunda nota
       media=(nota_1+nota_2)/2;  //o cálculo da média
       printf("\nMedia final: %.2f",media);  // mostrando a média
       if(media >= 7.0) //fazendo o teste condicional
           printf("\nAPROVADO"); //apresenta mensagem caso verdadeiro
       getch();
}
 
 

O "if" é um comando que contém uma ou mais instruções, e como você já viu, para mais que uma instrução é necessária a criação de bloco que será aberto e fechado por meio de chaves, mas isso só será necessário se dentro do "if" tiver mais de uma linha de comando, como no exemplo anterior tinha apenas um comando "printf", então não foi necessário abrir e fechar chaves. Veja o exemplo da condição a seguir:

 
if(media>=7.0)
{ //abrindo um bloco de instrução do comando  if
     printf("\nAPROVADO");
     printf("\nBom Aluno!");
} // fechando o bloco de instrução do comando if
 

Se não tivesse as chaves o compilador não executaria as instruções como desejado, apesar de não apresentar um erro a sua execução estaria com problemas, pois o resultado de sua execução nem sempre seria correto.

 

Atenção: A endentação é de suma importância para a interpretação do programa, por exemplo:

 
if(media >= 7.0)
  printf("\nAPROVADO");
printf("Bom Aluno!");
 

Neste caso observe que foram retiradas as chaves e feita a endentação e o programa irá escrever "Bom aluno" para qualquer condição, ou seja, mesmo que a média seja menor que 7.0, porque ele está interpretando que o printf("Bom aluno") está fora do "if" e realmente está, então a conclusão é a seguinte: "endentação e interpretadores de blocos (chaves) precisam de cuidados ao serem usados".

 
Composta
 

Essa estrutura vai ocorrer quando duas alternativas dependerem da mesma condição, ou seja, uma da condição ser verdadeira e a outra da condição ser falsa. Em algoritmo conhecemos o "se" e o "senao", agora vamos conhecer em C a instrução condicional composta que usa as palavras reservadas "if" (se) e "else" (senao), mas antes vamos a um exemplo...

 

Se o sexo de uma pessoa não for masculino, então a conclusão óbvia é que ela seja do sexo feminino e assim vice-versa... como você pôde observar dizer o sexo de uma pessoa também depende de uma certa lógica, observe que só será possível dizer se uma pessoa é de um determinado sexo se ela não pertencer ao oposto ("se" não for masculino "entao" é feminino).

 
            
 

O comando "else"(senao) será executado somente se o teste condicional do comando "if" for falso, ou seja, se a condição do "if" for falsa ele automaticamente entra no "else", em caso de seleção composta.

 

No nosso próximo exemplo, ao invés de apenas escrever se o aluno está "Aprovado" (média acima de 7.0), ou escrever se ele está "Reprovado" (média abaixo de 7.0), observe que se o aluno não estiver aprovado automaticamente ele estará reprovado.

 

Veja o exemplo:

 
/*
  SÍNTESE
    Objetivo: Calcular a media aritmética do aluno e informar
              a situação(APROVADO ou REPROVADO). 
    Entrada: Duas notas.
    Saída: Média final e a situação.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{    
    //Declarações
       float nota_1, nota_2, media;
    //Início
       printf("\nInforme a primeira nota: ");
       scanf("%f",&nota_1);    //lendo a primeira nota
       printf("\nInforme a segunda nota: ");
       scanf("%f",&nota_2);    //lendo a segunda nota
       media=(nota_1+nota_2)/2;  //o cálculo da média
       printf("\nMedia final: %.2f",media);  // mostrando a média
       if(media >= 7.0) //fazendo o teste condicional
       {
           printf("\nAPROVADO"); //escrevendo aprovado
           printf("\n Parabens");
       }       
       else{ // abrindo bloco de instrução
         printf("\nREPROVADO");  // escrevendo reprovado
         printf("\nEstude mais!");       
       }      
       getch();
}
 
 

Lembre-se: a condição obedece o princípio da não-contradição, ou seja, a condição nunca poderá ser verdadeira e falsa ao mesmo tempo, isso quer dizer que o programa só executa o que tem dentro do "if" ou só o que tem dentro do "else".

 

No nosso exemplo, como o teste da condição foi "falso" então o programa deixa de executar o bloco de instruções que estava dentro do "if" (mudou o fluxo) e executou o bloco de instruções que estava dentro do "else".

 

Como você observou, o else também pode possuir a abertura e fechamento de blocos (chaves), se for necessária a execução de várias instruções. No entanto, se somente uma instrução tiver que ser executada não será necessária a abertura e o fechamento do bloco.

 
Encadear ou Aninhar a seleção:
 

Para você se tornar um professor de faculdade no mínimo você tem que ser formado, ter uma pós-graduação, um mestrado e falar no mínimo duas línguas. Você percebeu que para você chegar a ser um professor universitário existem condições e que as mesmas tem que serem verdadeiras. Com a seleção aninhada é a mesma coisa, é o agrupamento de várias seleções, tal agrupamento ocorre quando um determinado bloco de instruções deve ser executado "se" um grupo de possibilidades ou combinações for satisfeito.

 
 

Observe a prática: O próximo programa irá receber três valores inteiros e irá informar o maior deles.

 
/*
  SÍNTESE
    Objetivo: Receber três valores e escrever o maior deles. 
    Entrada: Três valores.
    Saída: O maior valor
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{
   //Declarações
      int a,b,c,maior;
   //Início
   printf("Informe três valores:\n");
   scanf("%d%d%d",&a,&b,&c); //lendo os três valores
   if(a >= b)
       if(a >= c)  //só será testado se o "if" de fora for verdadeiro
            maior = a;
       else
            maior = c;
   else
       if(b >= c)
          maior=b;
       else
          maior=c;
   printf("\nMaior = %2d",maior);
   getch();
}
 
 

No exemplo acima, o terceiro valor informado (96) é o maior.

 

Acompanhe como isso aconteceu. Como o primeiro valor não é maior que o segundo, o teste do primeiro "if" deu "falso", automaticamente o programa executa o bloco de instruções que existe dentro do "else", mas dentro do "else" temos mais duas possibilidades, do segundo ser maior que o terceiro ou o terceiro ser maior que o segundo, é onde ocorre o teste do "if" que está dentro do "else", que também é "falso" e automaticamente o programa executa o que tem dentro do outro "else".

 
 

Um de seus questionamentos neste momento deve ser o seguinte: Por que não teve nenhum bloco iniciado e fechado com chaves, sendo que tem blocos que tem um "if" e um "else"? Lembre-se que o programa só executa ou um ou outro, nunca os dois. Portanto se ele executar o "if" ele não vai executar o "else", ou seja, o programa interpretará apenas uma instrução ou o "if" ou o "else".

 
Múltipla escolha:
 

Em algoritmo foi estudada a instrução escolha que será abordada agora como mais uma instrução de seleção possível na linguagem C

 

No tópico anterior foi falado sobre a seleção aninhada, mas será que ela é sempre a melhor opção para selecionar instruções que dependem da mesma condição? E se existirem inúmeras condições para selecionar as instruções? Caso existam muitas condições aninhadas a melhor opção é o "escolha" em "C" conhecido como "switch", onde o "caso" é substituído por "case" e o "caso contrário" por "default", mas lembre-se para selecionar uma instrução no "escolha" a condição analisada deverá ser um caracter ou um inteiro.

 

No exemplo a seguir nós vamos demonstrar a escolha de um dia da semana, em algoritmo usando a "seleção aninhada" e logo em seguida usando o "escolha", para você poder refletir qual seria a melhor opção. O programa estará recebendo do usuário um valor que será corespondente a um dia da semana.

 
 
algoritmo diasDaSemana;
//Síntese
    // Objetivo: escolher um numero corespondende a um dia da semana
    //Entrada: numero
    //Saída: dia da semana
principal  
//Declarações
  inteiro opcao;
  //Instruções
   escreval ("Digite um valor entre 1 e 7 correspondete aos dias da semana: ");
   leia(opcao);
   se (opcao == 1) entao
     escreval ("Domingo");
    senao
        se (opcao ==2) entao
          escreval ("Segunda-feira");
        senao
            se (opcao ==3) entao
              escreval ("Terça-feira");
			senao
                se (opcao ==4) entao
                  escreval ("Quarta-feira");
                senao
                    se (opcao ==5) entao
                      escreval ("Quinta-feira");
                    senao
                        se (opcao ==6) entao
                          escreval ("Sexta-feira");
                        senao
                            se (opcao ==7) entao
                              escreval ("Sabado");
                            senao
                                 escreval ("Valor invalido!");
                            fimSe
                        fimSe
                    fimSe
                fimSe
            fimSe
         fimSe
      fimSe


fimPrincipal
 
 

Utilizando a instrução "escolha":

 
algoritmo nomeAlgoritmo;
//Síntese
     //Objetivo: escolher um numero corespondende a um dia da semana
     // Entrada: numero
     // Saída: dia da semana 
principal
    //Declarações  
     inteiro opcao;
  //Instruções
	escreval ("Digite um valor entre 1 e 7 correspondete aos dias da semana: ");
	leia(opcao);
	escolha (opcao)   
	   caso 1 :
            escreval ("Domingo");
		    interrompa;
       caso 2 :
            escreval ("Segunda-feira");
            interrompa;
       caso 3 :
            escreval ("Terça-feira");
            interrompa;
       caso 4 :
            escreval ("Quarta-feira");
            interrompa;
       caso 5 :
            escreval ("Quinta-feira");
            interrompa;
       caso 6 :
            escreval ("Sexta-feira");
            interrompa;
       caso 7 :
            escreval ("Sabado");
            interrompa;
      outroCaso 
            escreval ("Valor invalido!");
fimPrincipal
 

Elaborando a implementação na linguagem C tem-se:

 

/*
  SíNTESE
    Objetivo: escolher um numero corespondende a um dia da semana
    Entrada: numero
    Saída: dia da semana
*//
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações
      int opcao;
   //Início
   printf ("Digite um valor entre 1 e 7 correspondete aos dias da semana: ");
  scanf("%d", &opcao);
  switch (opcao)
  { //selecionando o operador
        case 1 :
       printf ("Domingo\n");
     break;
     case 2 :
       printf ("Segunda-feira\n");
     break;
     case 3 :
        printf ("Terça-feira\n");
     break;
     case 4 :
        printf ("Quarta-feira\n");
     break;
     case 5 :
        printf ("Quinta-feira\n");
     break;
     case 6 :
        printf ("Sexta-feira\n");
     break;
     case 7 :
        printf ("Sabado\n");
     break;
     default :
       printf ("Valor invalido!\n");
  }
  getch();
  return 0;
}
 
 

O comando "break" que você viu logo após a linha de comando do "case", é chamado de comando de desvio, onde ele realiza um desvio incondicional. O "case" será executado até que o comando "break" ou o fim do "switch" seja alcançado.

 

Quando o comando "break" é alcançado salta para linha de código seguinte ao final do "switch". Caso não tivéssemos inserido o "break" o programa continuaria testando os outros "cases" e poderia causar um erro em seu programa.

 

Se você tem alguma dúvida sobre o "switch" vamos tentar tirá-la agora. Há três coisas importantes que você tem que saber sobre o comando "switch":

 
  • O comando "switch" difere do comando "if" porque "switch" só pode testar igualdade, enquanto "if" pode avaliar uma expressão lógica ou relacional;
  • Duas constantes "case" no mesmo "switch" não podem ter valores idênticos. Obviamente, um comando "switch" incluído em outro "switch" mais externo pode ter as mesmas constantes "case";
  • Se constantes de caractere são usadas em um comando "switch", elas são automaticamente convertidas para seus valores inteiros.
 
ESTRUTURAS DE REPETIÇÃO
 

Você já deve ter alguma intimidade com as estruturas de repetição, mas antes de começarmos logo na prática vamos relembrar alguns conceitos básicos.

 
 

Fazer um programa para calcular a média de duas notas de um aluno você já sabe fazer. Simples, não é? Agora imagine calcular a média de notas de 50 alunos. Será que é só escrever o algoritmo 50 vezes? É, pode até dar certo, porém nada viável.

 

Outro modo de resolver essa questão seria utilizar a mesma sequência de comandos novamente, ou seja, fazer um retrocesso ao início dos comandos para cada aluno, fazendo, portanto com que o fluxo de execução repetisse certo trecho do programa, o que nesta aplicação corresponderia escrever o mesmo trecho 50 vezes.

 

Existem três tipos de estruturas de repetição em algoritmo, são elas: para, enquanto e o repita. Em "C" temos respectivamente: for, while, do...while.

 

Vamos começar pelo o "for" que é uma estrutura de repetição finita, ou seja, possui limites fixos e uma variável de controle dentro desse limite.

 

A forma geral da repetição, também chamada de laço ou looping "for" em C é:

 
    for (<inicialização> ; <teste condicional> ; <incremento ou decremento>)
    {
        <instruções>;
    }
     
  • inicialização: É um comando de atribuição que é usado para colocar um valor na variável de controle (que deve ser declarada normalmente como outra variável qualquer) do laço;
  • teste condicional: É uma expressão relacional que determina quando o laço acaba, ou seja, enquanto condição verdadeira a repetição acontece;
  • incremento ou decremento: Define como a variável de controle deve variar a cada vez que o laço se repete.
 

Importante: observe que estas três seções são separadas por meio de ponto-e-vírgula (;).

 

Visando uma melhor fixação do conteúdo, vamos primeiro fazer um algoritmo para calcular a media de uma turma de 50 alunos em uma prova de algoritmo, usando a estrutura de repetição "para".

 
algoritmo nomeAlgoritmo;
//Síntese
     //Objetivo: Calcular a média de uma turma de 50 alunos em
     //            uma Prova de algoritmo usando "para"
     //Entrada: 50 notas.
     //Saída: Média geral da turma. 
principal
    //Declarações  
      real nota, acumulador, media;
      inteiro cont;
  //Instruções
      acumulador = 0;
      para (cont de 1 ate 50 passo 1) faca
        escreva("Informe a ",cont," nota: ");
        leia(nota);
        acumulador = acumulador + nota;
      fimPara
      media = acumulador / 50;
      escreva("Media geral:",media);
fimPrincipal
 

A implementação na linguagem C seria:

 
/*
  SÍNTESE
     Objetivo: Calcular a média de uma turma de 50 alunos em
               uma Prova de algoritmo usando "para"
     Entrada: 50 notas.
     Saída: Média geral da turma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações
     float nota, acumulador=0 ,media;
     int cont;
   //Início
      for(cont=1;cont<=50;cont++)
      {
         printf("Informe a %d nota:",cont);
         scanf("%f",&nota); //lendo a nota
         acumulador=acumulador+nota; //acumulando as 50
      }
      media=acumulador/50;  //calculando a média
      printf("\nMedia Geral =%2.1f",media);  //mostrando a média
      getch();     
}
 

Em nosso exemplo a variável de controle "cont" varia de 1 até 50, fazendo a leitura da nota e o acumulador repetir 50 vezes.

 

A média como só necessita ser calculada uma vez, ela tem que esta fora do bloco de comandos do "for".

 

ATENÇÃO: Como você observou foi necessário acumular as 50 notas, então nunca se esqueça de inicializar a variável (zero).

 

Observação: Como o laço "for" é um bloco de comando e como dentro do laço tem mais de uma linha de comando, ele também necessita de chaves.

 

Continuando com o laço "for"... Vamos imprimir na tela os número pares de 1 até 100. Para resolvermos esse problema existem várias formas, vamos resolver de algumas maneiras diferentes para treinarmos as versatilidades do laço "for".

 
/*
  SÍNTESE
     Objetivo: Imprimir na tela os números pares entre 1 e 100.
     Entrada: Nenhuma.
     Saída: Os números pares entre 1 e 100.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     int cont;
   //Início
     for(cont=1;cont<=100;cont++)
         if(cont%2==0) //testando para ver se é par
              printf("%1d-",cont);
     getch();
}
 
 

Como você pôde observar foi usada a variável de controle para obtermos os números pares, ou seja, podemos usar a variável de controle para fazermos o que quisermos, mas temos que tomar cuidado para não mudar a ordem do laço (incrementando ou decrementando a variável dentro do bloco também) a não ser que você use uma lógica para isso.

 

Vamos ver outra forma de mostrar os números pares mas só que agora em ordem decrescente de 100 até 2...

 
/*
  SÍNTESE
     Objetivo: Imprimir na tela os números pares entre 1 e 100.
     Entrada: Nenhuma.
     Saída: Os números pares entre 1 e 100.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     int cont;
   //Início
     for(cont=100;cont<=2;cont-2)
        printf("%1d-",cont);
     getch();
}
 
 

Desta vez mudamos a inicialização e a cada vez que a repetição ocorrer a variável será decrementada com 2. Com isso só basta escrever a variável de controle na tela.

 

Lembre-se: O "for" acontece de onde a variável de controle é inicializada até a 'condição' se tornar falsa, ou se preferir enquanto verdadeira.

 

Outra estrutura de repetição que já conhecemos chamada "enquanto", em "C" é chamada de "while".

 

Para relembrar, o "enquanto" ("while") é executado enquanto o teste de sua condição for verdadeiro ou até a condição se tornar falsa. A condição pode ser qualquer expressão, e lembre-se verdadeiro em "C" é qualquer valor não zero. Se já na primeira vez o resultado da condição for falso, os comandos não serão executados nenhuma vez, o que representa a característica principal desse modelo de repetição.

 

A forma geral do comando while é:

 
      while (<condição>)
      {
         <instruções>;
      }
 

Vamos utilizar o mesmo exemplo anterior, calcular a média de cinquenta alunos na prova de algoritmo, usando o "while". Mas espere aí, qual será a nossa condição de saída? A condição poderia ser quantidade de notas recebidas, ou seja, a quantidade de alunos menor que 50; porém, o que indica quantas vezes a nota foi acumulada? O "while" não oferece esse recurso, então teríamos que implementar um sistema de contagem, feito através de um 'contador' representado por uma variável com um dado valor inicial,que será incrementada a cada repetição.

 
/*
  SÍNTESE
     Objetivo: Calcular a média de uma turma de 50 alunos em  uma
                 prova de algoritmo usando a estrutura "while"
     Entrada: 50 notas.
     Saída: Média geral da turma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     float nota, acumulador=0, media;
     int contador=1;
   //Início
     while(contador<=50)   //teste da condição
     {
        printf("Informe a %d nota: ",contador);
        scanf("%f",&nota);  //lendo a nota
        acumulador=acumulador+nota;  //acumulando as 50
        contador++;  //incrementando o contador
     }
     media=acumulador / 50;   //calculando a média
     printf("\nMedia = :%2.1f",media);   //mostrando a média
     getch();
}
 
 

Observe que o laço irá repetir enquanto o "contador" estiver com um valor menor ou igual a 50.

 

No exemplo anterior tínhamos definido a quantidade de notas que iríamos acumular, mas e se nós tivéssemos que acumular notas de uma turma que não soubéssemos a quantidade de alunos, teríamos que admitir um "flag" de saída.

    "flag" é conhecido como um finalizador, em nosso próximo exemplo vamos admitir o valor finalizador como nota negativa;
 

Observe o exemplo a seguir:

 
/*
  SÍNTESE
     Objetivo: Calcular a média de uma turma de 50 alunos em  uma
                 prova de algoritmo usando a estrutura "while"
     Entrada: 50 notas.
     Saída: Média geral da turma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     float nota, acumulador=0, media;
     int contador=0;
   //Início
     printf("Informe a %d nota:",contador+1); //não altera o contador
     scanf("%f",&nota);
     while(nota>0) 
     {
        acumulador=acumulador+nota;  //acumulando as notas
        contador++;  //incrementando o contador
        printf("Informe a %d nota:",contador+1);
        scanf("%f",&nota);
     }
     media=acumulador/contador;   //calculando a média
     printf("\n\nMedia = %2.1f",media);
     printf("\nQuantidade = %2d",contador);  //mostrando a quantidade.
     getch();
}
 
 

Nesse caso o usuário poderá calcular quantas notas ele quiser, e para encerrar a repetição basta digitar uma nota negativa.

 

Vamos agora começar nossos estudos com a última estrutura de repetição a ser vista o "do...while" que em partes é a mesma coisa do "repita". O "do...while" se diferencia do "repita" no que se diz respeito a condição de saída. Por exemplo: o "repita" em algoritmo executa o laço até que a condição se torne verdadeira, ou seja, enquanto falso, já em "C" o "do...while", executa enquanto verdadeiro assim como o "for" e o "enquanto". Lembrando que o "do...while" também pode ser executado com "flag"(finalizador) de saída.

 

Neste exemplo vamos calcular a média de uma turma de 30 alunos usando o "do...while":

 
/*
  SÍNTESE
     Objetivo: Calcular a média de uma turma de 30 alunos em uma
                 prova de algoritmo usando a estrutura "do..while"
     Entrada: 30 notas.
     Saída: Média geral da turma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     float nota, acumulador=0, media;
     int contador=1;
   //Início
     do{
         printf("Informe a %d nota:",contador);
         scanf("%f",&nota);
         acumulador=acumulador+nota; //acumulando notas
         contador++;  //incrementando o contador
     } while(contador<=30);
     media=acumulador/contador;
     printf("\n\nMedia = %2.1f",media);  //mostrando a média
     printf("\nQuantidade = %2d",contador-1); //mostrando a quantidade.
     getch();
}
 
 

No exemplo anterior tivemos que inicializar o contador que controla o laço "do..while" com o valor 1, porque como já havíamos comentado ele executa todos os comandos antes de testar, então quando ele fizer o primeiro teste ele já vai ter executado o bloco uma vez. E na hora de escrever a quantidade de execuções, ou seja, as notas recebidas ele iria escrever uma execução a mais se não estivesse sido decrementado, porque o contador é incrementado antes do teste.

 
 

Afinal qual a diferença entre o "while" e o "do...while"? O "do...while" faz o seu teste condicional somente no final do bloco, isso quer dizer que ele primeiro executa o que tem no bloco, e só depois testa se a condição tem valor verdadeiro ou falso.

 

Seguindo o exemplo no qual admitimos como "flag" uma nota negativa, vamos fazê-lo novamente mas agora com o "do..while", para você ver a diferença entre o "while" e o "do...while".

 
/*
  SÍNTESE
     Objetivo: calcular a média de uma turma de X alunos em uma
                  Prova de algoritmo usando a estrutura "do while"
     Entrada: nota de cada aluno e o flag como nota negativa.
     Saída: a media geral da turma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     float nota,acumulador=0,media;
     int contador=0;
   //Início
     do{
        printf("Informe a %d nota:",contador+1);
        scanf("%f",&nota);
        acumulador=acumulador + nota;
        contador++;
     }while(nota>0);
     media=acumulador/contador;
     printf("\nMedia = %3.2f",media);  //mostrando a média
     printf("\nQuantidade = %2d",contador);  //mostrando a quantidade.
     getch();
}
 
 

Como você pode observar, o resultado não foi o esperado, porque como ele primeiro executou depois testou, quando foi digitado o valor negativo, além de contar a nota negativa como uma nota válida e acumular o valor negativo, também contou a nota como um cálculo válido.

 

A forma correta seria:

 
/*
  SÍNTESE
     Objetivo: calcular a média de uma turma de X alunos em uma
                  Prova de algoritmo usando a estrutura "do while"
     Entrada: nota de cada aluno e o flag como nota negativa.
     Saída: a media geral da turma.
*/
#include <stdio.h>  
#include <conio.h>
void main (void)
{   
   //Declarações     
     float nota,acumulador=0,media;
     int contador=0;
   //Início
     printf("Informe a %d nota:",contador+1);
     scanf("%f",&nota);
     do {
        acumulador=acumulador+nota;
        contador++;
        printf("Informe a %d nota:",contador+1);
        scanf("%f",&nota);   //lendo a nova nota
     }while(nota>0);
     media=acumulador/contador;
     printf("\nMedia = %2.1f",media);  //mostrando a média
     printf("\nQuantidade = %2d",contador); //mostrando a quantidade.
     getch();
}
 
 
Conclusão

    O comando "do...while" não é indicado para executar tarefas que necessitem serem testadas antes de executar.
 
Atividade de Fixação
 

No intuito de fixar a aprendizagem iniciada por meio deste módulo e verificar como seu entendimento sobre este conteúdo está, estão sendo sugeridos alguns exercícios de fixação para serem resolvidos. Clique no link de exercícios ao lado, pois será por meio dele iniciada a lista de exercícios sobre os conteúdos estudados até este momento nesta disciplina.