Baixe o app para aproveitar ainda mais
Prévia do material em texto
Algoritmos Aula 8 - Estrutura de repetição – Parte II Introdução Existem formas diferentes de se repetir uma atividade. Algumas atividades ficam repetindo, até que ocorra uma determinada situação. Outras que se repetem indefinidamente, outras que sabemos a quantidade de vezes que serão repetidas e variações sobre isso. Nesta aula, vamos ver os outros comandos em C++ que completam as estruturas de repetição e, assim, dar condições para você criar seus programas. Teoricamente, você já terá condições de criar a maioria dos programas com o “repertório” de conhecimento que adquiriu até aqui. Vamos lá! Boa aula! O que vimos e o que veremos Lá vamos nós de novo às estruturas de repetição! Vimos, na aula passada, que o for tem uma peculiaridade: ele é usado quando sabemos o número de vezes que uma repetição será executada. Mas existem situações nas quais não sabemos o número de repetições. Em outras situações, a repetição deve ocorrer pelo menos uma vez, e dependendo da condição, a repetição será ou não continuada. Vamos investigar esses detalhes. Vamos à primeira situação que estudaremos... Repetição com Limite do Contador Determinado pelo Usuário Ao ler o tipo de repetição, já podemos entender o que vai acontecer: a repetição será controlada por um contador determinado pelo usuário. Compare com o for, que você já conhece: embora sejamos nós programadores que digitamos a condição final, naquele momento não estamos desempenhando o papel do usuário, e sim do programador. Agora é diferente: é o usuário que vai determinar isso. Embora dê para fazer esta estrutura com o for, existe outro comando mais interessante para esta tarefa: o while (enquanto). Este comando tem a seguinte sintaxe: while (){ ‹ bloco de comandos › } Esquematicamente, o comando funciona de acordo com o seguinte diagrama: Veja, no diagrama, que o fluxo chega a uma condição (decisão) no qual será avaliada. Se for verdadeira, o fluxo passa para as instruções a serem executadas e volta à condição. Viu o looping aí? Enquanto a condição for verdadeira, o fluxo ficará “preso” a esse laço. Quando a condição for falsa, aí sim, ele se liberta e continua o programa. Portanto, evite criar condições que deixem o programa preso para sempre no looping, o chamado (e temido) looping infinito. Vamos programar então? Vamos lá! O exemplo é simples. Já que falamos algumas vezes de folha de pagamento, vamos fazer uma bem simples. O algoritmo consiste em ler do usuário um número de funcionários, que será o nosso contador. Para cada funcionário, será pedido o salário mensal, e este valor será somado ao valor da folha. O código do programa é: Veja que, na linha 11 até a 16, temos o while sendo controlado por uma variável que o usuário digitou. Se o usuário digitar 800, teremos 800 repetições (800 funcionários); se digitarmos 8, teremos 8 repetições e assim por diante. A linha 15 é muito importante e muitas vezes é esquecida pelos iniciantes. Sem ela, o looping cairá numa repetição infinita, o que, mais uma vez, é tudo o que não queremos. Nunca se esqueça de colocar dentro de um while a alteração da variável de controle! A cada repetição, a variável valor_folha é incrementada com o valor do salário lido. Veja a linha 14 e olhe o operador += que foi usado. Lembra-se dele, né? Para recordar, ele faz o mesmo que valor_folha = valor_folha + salario. Observe também o operador de incremento na linha 15. Fonte: https://www.youtube.com/embed/AgTrnkP2ja4 Fizemos uma demonstração com apenas 5 funcionários. No final, vimos o valor da folha de pagamento. É óbvio que uma folha de pagamento real tem, normalmente, mais funcionários e muito mais detalhes. E acredite, com o conhecimento que você tem, já daria para criar um programa para esse processo. Vamos agora continuar estudando o while com uma pequena variação. Repetição Controlada pelo Resultado de uma Operação Agora, veremos quando uma repetição não será controlada pelo programador nem pelo usuário, mas o próprio programa. Vamos ver como é isto por meio de um exemplo. Você sabe o que é MDC? É o máximo divisor comum. Dois números naturais sempre terão um máximo divisor comum. Por exemplo: os divisores comuns de 12 e 18 são 1, 2, 3 e 6; logo, 6 é o MDC entre 12 e 18, e anotamos assim: MDC (12,18) = 6. Para que serve o MDC? Exemplo Veja este exemplo obtido do site Brasil Escola: Uma indústria de tecidos fabrica retalhos de mesmo comprimento. Após realizarem os cortes necessários, verificou-se que duas peças restantes tinham as seguintes medidas: 156 centímetros e 234 centímetros. O gerente de produção, ao ser informado das medidas, deu a ordem para que o funcionário cortasse o pano em partes iguais e de maior comprimento possível. Como ele poderá resolver essa situação? Simples: com o MDC dos números 156 e 234. Texto padrão: O programa pede ao usuário que digite os dois números dos quais ele deseja encontrar o MDC. Isto ocorre nas linhas 6 a 8. A novidade ocorre na linha 10. Perceba que temos um comando chamado do, o qual abre um bloco de programação nesta mesma linha, o qual é fechado na linha 15 com o comando while, já nosso conhecido, e com uma condição: (num1>0). Agora, vamos conhecer o comando do-while. O objetivo dele é avaliar uma condição após um bloco de programação. Se a condição for verdadeira, o loop repete; se for falsa, o loop para e prossegue com o fluxo do programa. A sintaxe do comando é assim: do { comando; comando; ... } while (condição); Veja que obrigatoriamente pelo menos uma vez o bloco será executado. Esta é a maior característica dessa estrutura. Voltando ao nosso programa, ele segue um algoritmo chamado de “algoritmo óbvio”, que é derivado de outro algoritmo chamado de “algoritmo de Euclides” (que foi desenvolvido em 300 a.C.). Não vamos explicar agora o algoritmo; isto acontecerá na sua aula de Cálculo, mas essencialmente o algoritmo trabalha com o resto da divisão entre os dois números, que devem ser lidos em ordem crescente. O algoritmo entra em uma repetição, enquanto a repetição deixa a variável num1 positiva. A variável num1 tem o seu valor modificado pelo próprio programa durante a repetição, como se pode ver na linha 14. A linha 12 mostra a execução do programa passo a passo, apenas para informar ao usuário sobre o andamento do programa. Vamos ver o programa em funcionamento e ajudar o dono da fábrica de tecidos a saber qual comprimento do tecido ele deve cortar. Vamos ver o programa rodando? Assista ao vídeo a seguir: Fonte: https://www.youtube.com/embed/5H5bWGOpbIs Como podemos ver, o dono da fábrica deve cortar dois pedaços de 78 cm. Para esse caso, vimos que o programa executa poucas repetições. Porém, na segunda execução, para os números 317811 e 514229, o programa executa muito mais e não chega a um divisor máximo comum, e portanto, o MDC (317811,514229) = 1. Vimos a repetição controlada pelo usuário, pelo programador e pelo próprio programa. Agora vamos estudar mais uma forma de repetição que pode ser útil em vários programas, principalmente aqueles que apresentam um menu de escolha de opções. Repetição Controlada pelo Valor da Entrada de Dados Esta é uma variação da estrutura que vimos usando o for. Com o for, percebemos que ele é adequado para situações em que o número de repetições é bem definido e conhecido. Agora vamos ver uma variação desse tipo de estrutura, porémusando o comando while. Um bom exemplo é o cálculo do pi (π) usando uma série infinita, chamada de série de Gregory-Leibniz. Esta série tem o seguinte formato: Sabemos que podemos simplificar o valor de pi usando 3,14, mas em várias situações de cálculos trigonométricos ou outros que requerem maior precisão, temos que usar o pi com um número de casas mais significativos. Atenção Temos um detalhe: a série de Gregory-Leibniz só funciona bem com no mínimo 500.000 repetições. Você pode pensar que demoraria para retornar o resultado, mas isto vai depender do seu computador. Se o seu computador tiver um bom processador, com bastante memória RAM, em pouquíssimos segundos o resultado irá aparecer. Estávamos acostumados com poucas repetições, certo? Agora apareceu um programa mais exigente! Uma vez estabelecido o algoritmo, veja aqui uma possível solução para o problema em C++: 1 #include <iostream> 2 using namespace std; 3 4 int main (void){ 5 int num_termos,contador=1; 6 double pi=0,i=1.0; 7 8 cout<<"Quantos termos você deseja?"<<endl; 9 cin>>num_termos; 10 11 while (contador<=num_termos){ 12 pi += 4/i; 13 i+=2; 14 pi -= 4/i; 15 contador++; 16 i+=2; 17 } 18 cout<<"O valor de PI com "<<num_termos<<" termos = "<<pi<<endl; 19 return 0; 20 } Veja que, na listagem, mais uma vez aparecem os operadores de incremento nas linhas 12, 13, 14,15 e 16. Nós avisamos na aula passada que eles seriam bastante usados, não é? Observe também a linha 11, na qual aparece o operador relacional <=. O looping ocorre entre as linhas 11 e 17. Veja que, na condição, a variável num_termos foi informada pelo usuário e é a condição de parada da repetição. Na linha 15, aparece o incremento da variável contador. Mais uma vez, vale ressaltar: não se esqueça de colocar o incremento na variável da repetição, senão você já sabe: vai ocorrer um looping infinito! Agora, observe o programa sendo executado para 800.000 termos: https://www.youtube.com/embed/M1GlL3Dr1-w Executou rapidinho, né? O computador que executou o programa possui um bom processador, com bastante memória RAM. Em um computador com uma configuração um pouco mais modesta, não vai haver tanta diferença de tempo assim. Você viu que o resultado ficou com poucas casas decimais, e é o valor que costumamos usar. Na maioria das aplicações, esta aproximação está ótima. A não ser que você seja um astrofísico; neste caso, você precisará de um programa que exiba mais casas decimais, aliás, para cálculos astrofísicos normalmente são só 39 casas decimais! Vamos agora estudar mais uma variação de repetição. Repetição Controlada pela Resposta do Usuário Há muito tempo, em uma galáxia distante, os programas de computador não eram gráficos, cheio de cores, com mouse e sons bacanas, como hoje. Na atividade da aula passada, já vimos que as telas eram em modo texto e tinham que ser desenhadas usando caracteres disponíveis no sistema operacional. Olhe a tela a seguir. Esta é uma tela que usa um ambiente “gráfico”, mas que não impede o desenho pelo programador. Esse ambiente é chamado de Turbo Vision. Mas não se anime achando que nunca vai trabalhar com telas em modo texto. Muitos sistemas legados ainda usam este tipo de ambiente e, por incrível que pareça, é uma área na qual ainda existe demanda. Veja que existe um menu na parte superior e inferior da tela. Perceba que, enquanto o usuário não usar as teclas ALT-X, o sistema continuará em execução. Ou seja, preste atenção na frase: “Até que as teclas ALT e X sejam pressionadas, continue a executar o programa”; quer dizer, temos aí uma nova estrutura de repetição. A estrutura em que vamos trabalhar agora é útil para construir menus deste tipo. Exemplo É claro que não vamos fazer um menu como o da tela de exemplo, mas para simplificar, vamos criar um menu de um programa que ficará em execução até que a tecla ‘0’ seja pressionada. Veja o exemplo aqui. Atenção ao código: 1 #include <iostream> 2 using namespace std; 3 4 int main (void){ 5 int opcao; 6 do { 7 cout<<"\t\t\nMenu de Opcoes\n"; 8 cout<<"0. Sair\n"; 9 cout<<"1. Alo Mundo\n"; 10 cout<<"2. Falar Oi\n"; 11 cout<<"3. Repetir o menu\n"; 12 cout<<"4. Ler mais uma vez o menu\n"; 13 cout<<"Sua opcao: "; 14 cin>>opcao; 15 16 switch(opcao) { 17 case 0: 18 system("cls"); 19 cout<<"Tchau ...\n"; 20 break; 21 case 1: 22 system("cls"); 23 cout<<" Alo Mundo! \n"; 24 break; 25 case 2: 26 system("cls"); 27 cout<<" Oi! \n"; 28 break; 29 case 3: 30 case 4: 31 system("cls"); 32 break; 33 default: 34 system("cls"); 35 cout<<"Opção inválida! Tente novamente.\n"; 36 } 37 } while(opcao!=0); 38 } 2 Perceba que o programa “gira” em torno de uma estrutura do-while entre as linhas 6 e 37, e o “pulo do gato” é criar a condição da linha 37 (opcao!=0). O menu é implementado por uma estrutura switch e, dependendo da opção escolhida pelo usuário, o case correspondente será executado. O case 3, embora existente, não faz coisa alguma e por isso a chamada dele está como “Repetir o menu”. Em todos os cases, exceto o 3, existe um comando que até agora não foi usado, o system(“cls”). Como você percebeu, a finalidade dele é apagar a tela para que novas informações sejam impressas. Ele dá um efeito visual simples e bastante bacana para o programa. O maior ensinamento desse exemplo é mostrar que a repetição é controlada pela resposta do usuário e a opção digitada pelo usuário mostra isso e determina a quantidade de vezes que o programa será executado. Todos os programas que foram feitos até agora podem ter uma forma de opção como essa e mostrar uma pergunta para o usuário: “Deseja executar novamente?”. Tente fazer isso com os próximos programas. Loopings Aninhados Em várias situações, é necessário criar um algoritmo de repetição dentro do qual há outra repetição. Isso é mais comum do que você pensa. Quando falamos sobre a programação em modo texto, para pintar uma tela, como vimos no Turbo Vision, era necessário criar um looping dentro de outro. Na folha de pagamento (novamente), é preciso um looping para tratar todos os funcionários da empresa, e para cada funcionário, vários cálculos são feitos. Enfim, tenha certeza que você em breve vai encontrar em uma situação real. Veja a seguir as sintaxes possíveis para os laços aninhados: Exemplo Para finalizar, veja aqui um exemplo usando loops aninhados.. Observe um programa que mostra o fatorial dos números de 1 a 20: 1 #include <iostream> 2 using namespace std; 3 4 int main (void){ 5 long limite=20; 6 long fatorial=1; 7 8 for(int i=1;i<=limite;i++){ 9 fatorial=1; 10 for(int j=2;j<=i;j++) 11 fatorial*=j; 12 cout<<i<<"! = "<<fatorial<<endl; 13 } 14 return 0; 15 } A execução do programa resulta em: Atividades 1- Propomos à você um desafio usando loops aninhados. O objetivo é montar a seguinte saída: Veja que o usuário escolhe a quantidade de linhas que a figura vai ter. Para cada linha, será mostrada uma sequência decrescente da linha atual até 1, e depois outra sequência que vai de 1 até o valor da linha atual. Não esqueça de usar espaços para dar o efeito do triângulo desejado. Todos os espaços e demais efeitos visuais da figura são gerados por laços aninhados. Não é difícil, acredite. Bastapensar um pouquinho em como você vai compor os laços. O programa não deve permitir que o usuário digite valores menores que 6 nem maiores que 12. Bom trabalho! GABARITO http://estaciodocente.webaula.com.br/cursos/gra007/docs /a08_t08.pdf 2. O seguinte código deve imprimir os valores de 1 a 10: O código está correto? Não use o DevC++ para responder! Sim. Não, não é possível ter o cout <<n++. Não, a condição está errada. Não, faltam o { e } no bloco do while. Não, o correto é while(n=10). GABARITO A condição correta para imprimir de 1 a 10 é n<=10. 3. Analise os diagramas e depois responda quais estruturas de repetição eles se referem a (respectivamente). GABARITO While, do-while e for 4. No comando do-while, a expressão lógica associada ao ___(i)_____ é avaliada ____(ii)____ execução do bloco de comandos; no __(iii)______, a expressão lógica de controle é avaliada __(iv)______. Assinale a alternativa com as palavras que completam os espaços i, ii, iii e iv respectivamente: (i) do (ii) antes da (iii) while-do (iv) após. (i) while (ii) após a (iii) while-do (iv) antes. (i) do (ii) após a (iii) for (iv) antes. (i) while (ii) antes da (iii) while-do (iv) após. o (ii) após a (iii) for (iv) após. GABARITO A expressão lógica do while é avaliada em primeiro lugar e depois, se for verdadeira, executa o bloco. No do-while, a expressão lógica é avaliada após o blobo.
Compartilhar