capitulo 4 - comandos de repetição

28
60 Capítulo 4 Comandos de Repetição No mundo real, é comum a repetição de procedimentos para se realizar tarefas. Esses procedimentos não são repetidos eternamente, mas se encerram quando o objetivo é atingido. Por exemplo, quando uma pessoa aperta um parafuso, ela gira a chave de fenda uma vez, duas vezes etc. até que o parafuso esteja apertado o suficiente. Durante esse processo, é verificado, a cada volta, se o parafuso já está bem firme. Da mesma forma, podemos estruturar várias atividades diárias como repetitivas. Durante a chamada feita por um professor, por exemplo, ele chama os nomes enquanto não terminar a lista. Outras repetições podem ser quantificadas com antecedência. O aluno de castigo que precisa escrever 100 vezes no quadro negro: “Não vou fazer bagunça nunca mais”, executa a mesma instrução 100 vezes. Todas as repetições têm uma característica comum: o fato de haver uma verificação de condição que pode ser representada por um valor lógico, para determinar se a repetição prossegue ou não. Essa é a base para a implementação dos comandos de repetição em algoritmos. Em vez de fazermos um trabalho braçal, escrevendo a mesma instrução várias vezes, poderemos utilizar uma estrutura que indique que tal instrução será executada quantas vezes for necessária. 4.1 Comando enquanto Antes de vermos a sintaxe em nosso pseudocódigo, vejamos um exemplo do mundo real: o problema do elevador. Um elevador residencial tem um comportamento que pode ser descrito de forma algo- rítmica. Vejamos o seu funcionamento: Na subida: sobe cada andar, verificando se está em um andar selecionado dentro do elevador. Isso é feito até chegar ao andar mais alto selecionado dentro ou fora do elevador.

Upload: zueliton

Post on 16-Apr-2015

16 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Capitulo 4 - Comandos de Repetição

60

Capítulo 4Comandos de Repetição

No mundo real, é comum a repetição de procedimentos para se realizar tarefas. Esses

procedimentos não são repetidos eternamente, mas se encerram quando o objetivo é

atingido. Por exemplo, quando uma pessoa aperta um parafuso, ela gira a chave de fenda

uma vez, duas vezes etc. até que o parafuso esteja apertado o suficiente. Durante esse

processo, é verificado, a cada volta, se o parafuso já está bem firme.

Da mesma forma, podemos estruturar várias atividades diárias como repetitivas. Durante

a chamada feita por um professor, por exemplo, ele chama os nomes enquanto não

terminar a lista. Outras repetições podem ser quantificadas com antecedência. O aluno

de castigo que precisa escrever 100 vezes no quadro negro: “Não vou fazer bagunça

nunca mais”, executa a mesma instrução 100 vezes.

Todas as repetições têm uma característica comum: o fato de haver uma verificação de

condição que pode ser representada por um valor lógico, para determinar se a repetição

prossegue ou não. Essa é a base para a implementação dos comandos de repetição em

algoritmos. Em vez de fazermos um trabalho braçal, escrevendo a mesma instrução várias

vezes, poderemos utilizar uma estrutura que indique que tal instrução será executada

quantas vezes for necessária.

4.1 Comando enquantoAntes de vermos a sintaxe em nosso pseudocódigo, vejamos um exemplo do mundo

real: o problema do elevador.

Um elevador residencial tem um comportamento que pode ser descrito de forma algo-

rítmica. Vejamos o seu funcionamento:

• Na subida: sobe cada andar, verificando se está em um andar selecionado dentro

do elevador. Isso é feito até chegar ao andar mais alto selecionado dentro ou fora do

elevador.

Page 2: Capitulo 4 - Comandos de Repetição

61Capítulo 4 • Comandos de Repetição

enquanto não chegar ao andar mais alto selecionado interna/externamente façainício suba um andar, se o andar foi selecionado internamente então início pare, abra as portas, feche as portas, fimfim

• Na descida: desce cada andar, verificando se está em um andar selecionado den-

tro ou fora do elevador. Isso é feito até chegar ao andar mais baixo selecionado

dentro ou fora do elevador

enquanto não chegar ao andar mais baixo selecionado interna/externamente façainício desça um andar, se o andar foi selecionado interna/externamente então início pare, abra as portas, feche as portas, fimfim

O comando enquanto caracteriza-se por uma verificação de encerramento de atividades

antes de se iniciar (ou reiniciar) a execução de seu bloco de instruções. Dessa forma,

no algoritmo do elevador, antes de subir/descer um andar é verificado se o andar atual

é o mais alto/baixo selecionado. Caso não seja, um conjunto de atividades é executado

(sobe/desce um andar, verifica se é um andar selecionado e abre (ou não) as portas).

Vejamos sua sintaxe:

enquanto <valor booleano> faça <bloco de instruções><continuação do algoritmo>

Voltemos ao exemplo do aluno de castigo. Fazer um algoritmo que escrevesse para ele,

cem vezes, “Não vou fazer mais bagunça”, antes deste capítulo, seria uma tarefa inglória.

O algoritmo seria semelhante ao descrito a seguir.

Algoritmo Lição_Aluno_Versão1

início escreva(“Não vou fazer mais bagunça!”); escreva(“Não vou fazer mais bagunça!”); escreva(“Não vou fazer mais bagunça!”); escreva(“Não vou fazer mais bagunça!”);... { O comando precisa ser escrito 100 vezes... }fim

Page 3: Capitulo 4 - Comandos de Repetição

62 Algoritmos e Programação

Para que possamos utilizar o comando de repetição, precisaremos verificar, de alguma

forma, se o comando já foi executado 100 vezes.

enquanto <não foi executado 100 vezes o próximo bloco > faça escreva(“Não vou fazer mais bagunça!”);

Bem, o problema reside em implementar essa verificação. Uma estratégia muito comum

para esse tipo de situação é acompanhar a execução das repetições contando cada vez

que o bloco é executado. Cada execução do bloco de instruções é chamada iteração. O

próprio comando de repetição em conjunto com seu bloco de instruções é conhecido

como loop ou laço.

Para que tenhamos a informação de quantas iterações já foram realizadas no laço, neces-

sitaremos de uma variável que fará o papel de contador. Essa variável conterá o número

de iterações já realizadas, sendo atualizada a cada nova iteração.

4.1.1 Problema 11 – Escrever 100 vezes "Não vou fazer mais bagunça"

Faça um algoritmo que escreva 100 vezes o texto: “Não vou fazer mais bagunça”, utili-

zando um comando de repetição.

Algoritmo Lição_Aluno_Versão2

var contador: inteiro;início contador 0; { Nenhuma iteração foi feita até aqui } enquanto (contador < 100) faça { O bloco será repetido 100 vezes } início escreva(“Não vou fazer mais bagunça!”); contador contador + 1; { A cada iteração, conta-se mais 1 } fimfim

Vejamos a seguir outros exemplos.

4.1.2 Problema 12 – Ler 100 números e calcular a soma e a média

Faça um algoritmo que leia 100 números e retorne a soma e a média desses valores.

Algoritmo Soma_Média100

var contador: inteiro; valor, soma, média: real;início

1 contador 0; { Nenhuma iteração foi feita até aqui }2 soma 0; { Ainda não foi somado nenhum valor }3 enquanto (contador < 100) faça { O bloco será repetido 100 vezes }

Page 4: Capitulo 4 - Comandos de Repetição

63Capítulo 4 • Comandos de Repetição

início4 escreva(“Entre com um valor: ”);5 leia(valor);6 soma soma + valor;7 contador contador + 1; { A cada iteração, conta-se mais 1 }

fim8 média soma / contador;9 escreva(“Soma: “, soma);10 escreva(“Média: ”, média);

fim

É interessante verificar o processo de acumulação de valores feito na variável soma

(linha 6). Seu valor é atualizado a cada iteração, somando-se seu valor atual com o

novo valor lido. Para que isso funcione, é importante que o valor inicial da variável seja

definido antes da entrada do laço, para que um valor desconhecido não seja atribuído

na primeira iteração do laço.

Vejamos o teste de mesa para a melhor compreensão do processo. Para viabilizar a

realização do teste de mesa, consideremos o laço até 3 e não até 100, como está no

algoritmo (Tabela 4.1).

Entrada: 5, 4, 9 (ou seja, os valores que serão entrados pelo usuário serão 5, 4 e 9, nesta

seqüência).

Tabela 4.1 – Teste de mesa para Soma_Média100

Instrução Linha contador valor soma média1 1 0 ? ? ?2 2 0 ? 0 ?3 3 0 ? 0 ?4 4 0 ? 0 ?5 5 0 [5] 0 ?6 6 0 5 5 ?7 7 1 5 5 ?8 3 1 5 5 ?9 4 1 5 5 ?

10 5 1 [4] 5 ?11 6 1 4 9 ?12 7 2 4 9 ?13 3 2 4 9 ?14 4 2 4 9 ?15 5 2 [9] 9 ?16 6 2 9 18 ?17 7 3 9 18 ?18 3 3 9 18 ?19 8 3 9 18 620 9 3 9 {18} 621 10 3 9 18 {6}

Page 5: Capitulo 4 - Comandos de Repetição

64 Algoritmos e Programação

Note que a condição de entrada/saída do laço está na linha 3. Esse teste é executado nas

instruções 3, 8, 13 e 18. Perceba também que o teste é repetido sempre após o bloco de

instruções (linha 7) pertencente ao laço. Quando a condição é verdadeira, a instrução a

ser executada é a do início do bloco, na linha 4 (instruções 4, 9 e 14). Porém, na instrução

18, a condição é falsa (no nosso teste, estamos considerando enquanto contador < 3)

e a próxima instrução a ser executada (instrução 19) está na linha 8, após o bloco de

instruções pertencente ao comando enquanto.

Exercício proposto

1. Adapte o algoritmo Soma_Média100 para que o número de valores a ser computado

seja determinado a partir de uma variável de entrada e não como um valor fixo no

programa, como fora definido.

4.1.3 Problema 13 – Calcular a multiplicação de dois números sem o operador "*"

Faça um algoritmo que calcule a multiplicação de dois números inteiros sem utilizar o

operador “*”. Em vez disso, utilize apenas o operador de adição “+”.

Para implementar esse algoritmo, devemos lembrar que qualquer multiplicação pode

ser expressa por meio de somas. Por exemplo, o resultado da expressão 6 * 3 é o mesmo

de 6 + 6 + 6 ou 3 + 3 + 3 + 3 + 3 + 3. Ou seja, soma-se um elemento com ele próprio o

número de vezes do segundo elemento.

Algoritmo Mult_Soma

var contador: inteiro; operando1, operando2, resultado, contador: inteiro; início

1 contador 0; { Nenhuma iteração foi feita até aqui }2 resultado 0; { Ainda não foi somado nenhum valor }3 escreva(“Entre com o primeiro valor: ”);4 leia(operando1);5 escreva(“Entre com o segundo valor: ”);6 leia(operando2);7 enquanto (contador < operando2) faça { O bloco será repetido “operando2” vezes }

início8 resultado resultado + operando1;9 contador contador + 1; { A cada iteração, conta-se mais 1 }

fim10 escreva(“O resultado da multiplicação é: “,resultado);

fim

Exercícios propostos

1. Faça três testes de mesa para o algoritmo anterior com as seguintes entradas: 0, 3;

3, 6 e 6, 3.

Page 6: Capitulo 4 - Comandos de Repetição

65Capítulo 4 • Comandos de Repetição

2. Se você fez o exercício anterior, pode notar que o número de instruções a serem

executadas para a segunda e a terceira entrada é diferente, apesar de o resultado ser

o mesmo. Isso porque sempre o operando1 será somado e o operando2 determinará

quantas vezes o laço será repetido. Melhore o algoritmo para que o valor maior seja

somado e o valor menor seja o determinante para o controle do laço, garantindo

assim que o menor número de instruções seja executado para qualquer entrada,

independentemente de sua ordem.

4.1.4 Problema 14 – Calcular o fatorial de um número

Faça um algoritmo que leia um número inteiro e calcule o seu fatorial. Se o número for

negativo, informe que o valor é inválido.

Sabemos que o fatorial de um número n, representado por n!, é dado por:

n * (n - 1) * (n - 2) *... * 1, para n > 0 e n! = 1 para n = 0

Como dito anteriormente, um ponto crucial para resolver um problema que inclua a

repetição é a definição do ponto de saída do laço. Além disso, é importante se definir a

situação desejada para a entrada no laço e o que vai ser executado em cada iteração.

Nesse problema, o laço só pode se iniciar após a leitura do valor n e a verificação se tal

valor é válido. Caso o valor seja 0, o fatorial deve ser retornado como 1 e o comando de

repetição não precisa ser executado.

A cada iteração dentro do laço, é necessário acumular o resultado da multiplicação do

valor pelo subseqüente (n * n - 1 *...). Também é preciso subtrair 1 do último valor que

foi multiplicado, preparando-o para a próxima iteração ou para a saída do laço.

A saída do laço é feita quando o valor a ser multiplicado chegar a 1.

Algoritmo Fatorial

var valor, fat, n: inteiro;início escreva(“Entre com um valor: ”); leia(valor); se (valor < 0) então escreva(“Valor inválido!”); senão início fat 1; n valor; enquanto (n > 1) faça início fat fat * n; n n – 1; { A cada iteração, diminui-se 1 } fim escreva(“O fatorial calculado é: “, fat); fimfim

Page 7: Capitulo 4 - Comandos de Repetição

66 Algoritmos e Programação

Note que o valor inicial de fat é 1 e não 0, como se poderia imaginar. Isso porque o ele-

mento neutro na multiplicação é o 1 e não o 0, como na adição, ou seja, qualquer número

multiplicado por 1 é ele próprio, assim como acontece com o 0 em relação à adição.

O fatorial de 1 ou 0 é calculado implicitamente, já que nesses casos o laço não é exe-

cutado, pois a condição de controle do laço (n > 1) não é satisfeita nenhuma vez e o

valor do fatorial permanece em 1, como esperado. Esta situação ilustra o fato de que o

bloco de instruções pertencente ao laço pode não ser executado nenhuma vez, caso a

condição de controle não seja satisfeita na primeira passagem.

Exercício proposto

1. Faça dois testes de mesa referentes ao algoritmo Fatorial para o cálculo do fatorial

dos números 1 e 5.

4.2 Comandos de repetição combinados com comandos de condiçãoA utilização de comandos de repetição combinados com comandos de condição permite

resolver problemas bem mais complexos que os vistos até agora. Na realidade, o ferra-

mental já apresentado é a base para toda a seqüência de algoritmos, e sua compreensão é

absolutamente fundamental para o desenvolvimento de algoritmos mais sofisticados.

Os comandos de condição podem fazer parte de blocos pertencentes a comandos de

repetição e vice-versa. Ou seja, estruturas como as descritas a seguir podem ocorrer

intercaladas quantas vezes forem necessárias.

Exemplo:

... se <valor booleano> então início ... enquanto <valor booleano> faça início ... fim ... fim { Fim do bloco se } senão início ... enquanto <valor booleano> faça início ... se <valor booleano> então início .... fim senão

Page 8: Capitulo 4 - Comandos de Repetição

67Capítulo 4 • Comandos de Repetição

início .... fim .... fim { Fim do bloco enquanto } .... fim { Fim do bloco senão } <continuação do algoritmo>fim

Na estrutura anterior temos comandos de decisão aninhados a comandos de repetição

e vice-versa. Esse tipo de estrutura é extremamente útil para resolver problemas em

diversas situações. Vejamos a seguir alguns exemplos.

4.2.1 Problema 15 – Calcular a soma dos números ímpares de um intervalo

Faça um algoritmo que calcule a soma de todos os números ímpares dentro de uma

faixa de valores determinada pelo usuário.

Um número é ímpar quando sua divisão por 2 não é exata, ou seja, o resto resultante da

divisão inteira do número por 2 tem valor 1. Vejamos como fica o código:

se ((número resto 2) = 1) então <código para número ímpar>[senão <código para número par>]

Como o algoritmo solicita a soma dos valores ímpares dentro de uma faixa, teremos

que fazer o acúmulo do resultado apenas quando a condição ímpar for atendida. Essa

condição será testada para todos os números dentro da faixa, por meio de um laço.

Algoritmo Soma_Ímpares_Versão1

var inferior, superior, num, soma: inteiro;início soma 0; escreva(“Entre com o limite inferior: “); leia(inferior); escreva(“Entre com o limite superior: “); leia(superior); num inferior; enquanto (num <= superior) faça início se (num resto 2 = 1) então soma soma + num; num num + 1; fim escreva(“Somatório: “, soma);fim

Page 9: Capitulo 4 - Comandos de Repetição

68 Algoritmos e Programação

Exercícios propostos

1. Faça o teste de mesa com intervalo definido entre 4 e 13.

2. Adapte o algoritmo Soma_Ímpares_Versão1 para obrigar o usuário a entrar com um

valor para o limite inferior menor que o valor definido para o limite superior. Para isso,

faça um laço que garanta a entrada de um intervalo válido (inferior < superior).

3. Adapte o algoritmo Soma_Ímpares_Versão1. Substitua o teste em que verificamos

se o número é ímpar dentro do laço para, então, acumulá-lo à variável soma pela

seqüência:

a. Faça um único teste antes do laço.

b. Determine se o número é ímpar e considere como limite inferior o próximo

ímpar (ou o próprio número caso este seja ímpar).

c. Faça o laço aumentando 2 a 2 seu valor para que apenas os números ímpares

sejam calculados, sem a necessidade de novas verificações.

4. Faça o teste de mesa dos algoritmo Soma_Ímpares_Versão1 adaptado no exercí-

cio proposto 3, considerando os limites 4 e 13. Compare o número de instruções

executadas com o teste de mesa do algoritmo Soma_Ímpares_Versão1 (visto no

exercício 1).

4.2.2 Problema 16 – Determinar se um número é primo

Faça um algoritmo que leia um número inteiro positivo e determine se este é primo ou

não.

Por definição, um número é primo quando é divisível somente por si próprio e por 1.

Portanto, para determinar se um número é primo, temos de definir por quais números

é divisível. A aproximação mais simples, e que podemos dizer ser uma aproximação

de “força bruta”, poderia ser testar a divisibilidade do número avaliado por todos os

números menores que ele. Vejamos a implementação deste algoritmo.

Algoritmo Primo_Versão1

var número, divisor: inteiro; divisível: booleano; { Variáveis booleanas são úteis para determinar a saída ou não de laços }

início escreva(“Entre com um número a ser testado: ”); leia(número); divisível F;

Page 10: Capitulo 4 - Comandos de Repetição

69Capítulo 4 • Comandos de Repetição

divisor número – 1; enquanto (não(divisível) e divisor > 1) faça início se (número resto divisor = 0) então divisível V; senão divisor divisor – 1; fim se (não(divisível)) então escreva(“O número “, número, “ é primo.”); senão escreva(“O número “, número, “ não é primo.”);fim

Apesar de o algoritmo Primo_Versão1 ser eficaz, visto que resolve o problema para o

qual foi projetado, não se pode dizer que seja propriamente eficiente. Basta que anali-

semos com um pouco mais de profundidade que perceberemos que várias otimizações

podem ser aplicadas ao raciocínio utilizado nesse algoritmo. Vejamos:

1. Números pares (com exceção do 2) não podem ser primos, visto que são divisíveis por

2. Se um número não for divisível por 2, não será divisível por nenhum outro número

par. Portanto, com exceção do número 2, só precisaremos testar números ímpares.

2. É mais fácil que um número seja divisível por um número pequeno do que por um

número maior. Portanto, se iniciarmos a procura do divisor de baixo para cima, ao

invés de cima para baixo, como foi implementado, teremos chance de encontrar o

número muito antes.

3. Nenhum número pode ser divisível por outro número maior que a metade dele.

Portanto, não precisamos testar a divisibilidade dos número na faixa entre a metade

e o próprio número.

Se levarmos em conta tais considerações, teremos um algoritmo muito mais eficiente que

o anterior, pois executará muito menos instruções para responder a mesma questão.

Algoritmo Primo_Versão2

var número, divisor: inteiro; divisível: booleano;início escreva(“Entre com um número a ser testado: ”); leia(número); divisível F; se (número resto 2 = 0 e número > 2) então { Número par diferente de 2 } divisível V; senão divisor 3; { Esta condição será falsa se o número for par } enquanto (não(divisível) e divisor <= número / 2) faça { Números ímpares menores que 6 são primos e não precisam entrar no laço }

Page 11: Capitulo 4 - Comandos de Repetição

70 Algoritmos e Programação

início se (número resto divisor = 0) então divisível V; senão divisor divisor + 2; { Serão testados divisores ímpares: 3, 5.. } fim se (não(divisível)) então escreva(“O número “, número, “ é primo.”); senão escreva(“O número “, número, “ não é primo.”);fim

Um raciocínio mais sofisticado pode ainda nos dar uma otimização final. Vejamos alguns

exemplos para facilitar a compreensão deste ponto:

• 15 é divisível pelos números 1, 3, 5 e 15 (1 * 15, 3 * 5, 5 * 3 e 15 * 1).

• 16 é divisível pelos números 1, 2, 4, 8 e 16 (1 * 16, 2 * 8, 4 * 4, 8 * 2 e 16 * 1).

• 17 é divisível pelos números 1 e 17 (1 * 17, e 17 * 1).

• 20 é divisível pelos números 1, 2, 4, 5, 10 e 20 (1 * 20, 2 * 10, 4 * 5, 5 * 4, 10 * 2 e 20 * 1).

• 25 é divisível pelo números 1, 5 e 25 (1 * 25, 5 * 5 e 25 * 1).

• 36 é divisível pelo números 1, 2, 3, 4, 6, 9, 12, 18 e 36 (1 * 36, 2 * 18, 3 * 12, 4 * 9, 6 * 6,

9 * 4, 12 * 3, 18 * 2 e 36 * 1).

Os exemplos anteriores são para ilustrar a seguinte propriedade da divisibilidade de

um número: qualquer número que seja divisível por outro terá como divisores dois nú-

meros ou fatores, e um será maior que o outro, a não ser que tais números sejam iguais

(quando o número tem uma raiz quadrada exata). No caso de divisores diferentes, o

número menor sempre será menor que a raiz quadrada do resultado da multiplicação e

o número maior, maior que a raiz quadrada do número em questão.

Podemos perceber que quanto maior um dos fatores, menor o outro. A relação se in-

verte após a linha da raiz quadrada, quando os números se repetem em ordem inversa.

Podemos, então, concluir que se um número não for divisível por um número menor

ou igual à sua raiz quadrada, não terá outro divisor que não ele próprio ou o 1. Ou seja,

será um número primo. Portanto, só precisamos testar a divisibilidade de um número

por valores iguais ou inferiores à sua raiz quadrada. Adaptando o algoritmo, teremos o

que se vê no exemplo a seguir.

Algoritmo Primo_Versão3

var número, divisor: inteiro; divisível: booleano;

Page 12: Capitulo 4 - Comandos de Repetição

71Capítulo 4 • Comandos de Repetição

início escreva(“Entre com um número a ser testado: ”); leia(número); divisível F; se (número resto 2 = 0 e número > 2) então { Número par } divisível V; senão divisor 3; enquanto (não(divisível) e divisor <= número raiz 2) faça { Números ímpares menores que 9 são primos e não precisam entrar no laço } início se (número resto divisor = 0) então divisível V; senão divisor divisor + 2; { Serão testados números ímpares: 3, 5, ... } fim se (não(divisível)) então escreva(“O número “, número, “ é primo.”); senão escreva(“O número “, número, “ não é primo.”);fim

Exercício proposto

1. Faça dois testes de mesa referentes aos três algoritmos que identificam um número

primo. Verifique as seguintes entradas: 15 e 29. Verifique qual o número de instruções

é necessário executar em cada uma delas e veja a diferença entre suas execuções.

4.3 Comandos de repetição encadeadosApesar de seguir o mesmo padrão de encadeamento de outros comandos já vistos, a

utilização de comandos de repetição encadeados geralmente causa uma certa dificuldade

para o seu acompanhamento à primeira vista.

A estrutura do algoritmo que contém laços encadeados segue:

<nome do algoritmo><declaração de variáveis>início ... enquanto <valor booleano> faça início ... enquanto <valor booleano> então início .... fim { Fim do bloco enquanto interno } .... fim { Fim do bloco enquanto externo } .... <continuação do algoritmo>fim

Page 13: Capitulo 4 - Comandos de Repetição

72 Algoritmos e Programação

De fato, podemos ter tantos laços encadeados quanto precisarmos. E ainda podemos

tê-los combinados com comandos de decisão e assim por diante.

Até agora, usamos os laços para fazer operações sobre um conjunto de elementos. Por

exemplo, no caso da soma dos números primos, tínhamos que executar um bloco de

condição para cada possível divisor do número em questão. No caso da soma de 100

números, os números entrados eram acumulados dentro do laço, repetindo-se o pro-

cesso para cada número.

A utilização de laços encadeados pode ser necessária quando precisamos fazer uma

operação repetitiva para cada elemento dentro de um conjunto. Imaginemos que preci-

sássemos calcular a média das notas de uma classe. Até aí, um único laço seria suficiente.

Porém, imaginemos agora que precisássemos calcular a média das notas de todas as

turmas de uma escola. As turmas são um conjunto. As notas dos alunos dentro de cada

turma são outro conjunto. Para cada conjunto, precisaríamos de um laço, nesse caso, dois

laços encadeados. E se precisássemos ainda fazer o cálculo para todas as escolas de uma

cidade. Nesse caso precisaríamos de três laços encadeados (escolas/turmas/alunos).

4.3.1 Problema 17 – Calcular a média das turmas de uma escola

Faça um algoritmo que calcule a média de todas as turmas de uma escola. Considere

como entradas o número de turmas e o número de alunos de cada turma. A média de

cada turma deve ser apresentada, além da média geral, que será o resultado da média

das turmas.

Um detalhe importante de se notar na resolução desse tipo de algoritmo é o fato de os

laços geralmente terem condições diferentes e independentes. Podemos até mesmo resol-

ver um exercício de cada vez, abstraindo um dos laços e se concentrando no segundo.

Vejamos, então, a solução do problema para apenas uma turma, para depois resolvermos

o problema de todas as turmas:

Algoritmo Média_Turma

var cont, alunos: inteiro; nota, soma, média: real;início

1 cont 0; { Nenhuma iteração foi feita até aqui }2 soma 0; { Ainda não foi somado nenhum valor }3 escreva(“Entre com o número de alunos”);4 leia(alunos);5 enquanto (cont < alunos) faça { Será repetido para cada aluno da turma }

início6 escreva(“Entre com a nota do aluno: ”, cont + 1);7 leia(nota);

Page 14: Capitulo 4 - Comandos de Repetição

73Capítulo 4 • Comandos de Repetição

8 soma soma + nota;9 cont cont + 1;

fim10 média soma / alunos;11 escreva(“A média da turma é: ”, média);

fim

Agora, vamos resolver o que seria o cálculo das médias de uma escola, considerando

que temos as médias de cada turma já preparadas pelo usuário.

Algoritmo Média_Escola_Versão1

var cont, turmas: inteiro; média_turma, soma, média_escola: real; início

1 cont 0; { Nenhuma iteração foi feita até aqui }2 soma 0; { Ainda não foi somado nenhum valor }3 escreva(“Entre com o número de turmas: ”);4 leia(turmas);5 enquanto (cont < turmas) faça { Será repetido para cada turma }

início6 escreva(“Entre com a média da turma: ”, cont + 1);7 leia(média_turma);8 soma soma + média_turma;9 cont cont + 1;

fim10 média_escola soma / turmas;11 escreva(“A média da escola é: ”, média_escola);

fim

Bem, resolvemos as duas partes do algoritmo. Entretanto, a parte da média das escolas

conta com uma situação que não temos: a média de cada turma não é conhecida de an-

temão pelo usuários, a não ser que estes executassem o primeiro algoritmo, anotassem

num papel o resultado de cada turma e executassem o segundo algoritmo para passar

esses valores. É claro que esta solução não é razoável.

De fato, o que precisa ser feito é substituir o trecho do segundo algoritmo em que o

usuário entra com as médias das turmas pelo primeiro algoritmo, que é quem calcula

a média de cada turma. Atenção especial deve ser dada ao possível conflito de variá-

veis. Por exemplo, os contadores utilizados nos dois algoritmos tratam de elementos

diferentes (alunos e turmas, respectivamente) e devem ser tratados como variáveis

independentes.

Algoritmo Média_Escola_Versão2var cont_a, alunos, cont_t, turmas: inteiro; nota, média_turma, soma_turma, média_escola, soma_escola: real;

Page 15: Capitulo 4 - Comandos de Repetição

74 Algoritmos e Programação

início1 cont_t 0; { O laço externo, da escola, em que cada turma será contada }2 soma_escola 0; 3 escreva(“Entre com o número de turmas: ”);4 leia(turmas);5 enquanto (cont_t < turmas) faça { Será repetido para cada turma da escola }

início6 cont_a 0; { O laço interno, da turma, em que cada aluno será contado }7 soma_turma 0; 8 escreva(“Entre com o número de alunos da turma ”, cont_t + 1);9 leia(alunos);10 enquanto (cont_a < alunos) faça { Será repetido p/ cada aluno da turma }

início11 escreva(“Entre com a nota do aluno: ”, cont_a + 1);12 leia(nota);13 soma_turma soma_turma + nota;14 cont_a cont_a + 1; { A cada iteração, mais um aluno }

fim15 média_turma soma_turma / alunos;16 escreva(“A média da turma ”, cont_t + 1, “ é: ”, média_turma);17 soma_escola soma_escola + média_turma;18 cont_t cont_t + 1; { A cada iteração, mais uma turma }

fim19 média_escola soma_escola / turmas;20 escreva(“A média da escola é: ”, média_escola);

fim

Para facilitar o teste, acompanhemos o teste de mesa considerando uma escola com duas

turmas com 3 e 2 alunos cada uma (Tabela 4.2).

Tabela 4.2 – Teste de mesa para Média_Escola_Versão2

Instrução Linha cont_a alunos nota cont_t turmas média_turma

soma_turma

média_escola

soma_escola

1 1 ? ? ? 0 ? ? ? ? ?

2 2 ? ? ? 0 ? ? ? ? 0

3 3 ? ? ? 0 ? ? ? ? 0

4 4 ? ? ? 0 [2] ? ? ? 0

E 5 5 ? ? ? 0 2 ? ? ? 06 6 0 ? ? 0 2 ? ? ? 07 7 0 ? ? 0 2 ? 0 ? 08 8 0 ? ? {0} 2 ? 0 ? 09 9 0 [3] ? 0 2 ? 0 ? 0

I 10 10 0 3 ? 0 2 ? 0 ? 0

11 11 {0} 3 ? 0 2 ? 0 ? 0

12 12 0 3 [7,5] 0 2 ? 0 ? 0

13 13 0 3 7,5 0 2 ? 7,5 ? 0

Page 16: Capitulo 4 - Comandos de Repetição

75Capítulo 4 • Comandos de Repetição

Instrução Linha cont_a alunos nota cont_t turmas média_turma

soma_turma

média_escola

soma_escola

14 14 1 3 7,5 0 2 ? 7,5 ? 0

I 15 10 1 3 7,5 0 2 ? 7,5 ? 0

16 11 {1} 3 7,5 0 2 ? 7,5 ? 0

17 12 1 3 [5] 0 2 ? 7,5 ? 0

18 13 1 3 5 0 2 ? 12,5 ? 0

19 14 2 3 5 0 2 ? 12,5 ? 0

I 20 10 2 3 5 0 2 ? 12,5 ? 0

21 11 {2} 3 5 0 2 ? 12,5 ? 0

22 12 2 3 [5,5] 0 2 ? 12,5 ? 0

23 13 2 3 5,5 0 2 ? 18 ? 0

24 14 3 3 5,5 0 2 ? 18 ? 0

I 25 10 3 3 5,5 0 2 ? 18 ? 0

26 15 3 3 5,5 0 2 6 18 ? 0

27 16 3 3 5,5 {0} 2 {6} 18 ? 0

28 17 3 3 5,5 0 2 6 18 ? 6

29 18 3 3 5,5 1 2 6 18 ? 6

E 30 5 3 3 5,5 1 2 6 18 ? 6

31 6 0 3 5,5 1 2 6 18 ? 6

32 7 0 3 5,5 1 2 6 0 ? 6

33 8 0 3 5,5 {1} 2 6 0 ? 6

34 9 0 [2] 5,5 1 2 6 0 ? 6

I 35 10 0 2 5,5 1 2 6 0 ? 6

36 11 {0} 2 5,5 1 2 6 0 ? 6

37 12 0 2 [8] 1 2 6 0 ? 6

38 13 0 2 8 1 2 6 8 ? 6

39 14 1 2 8 1 2 6 8 ? 6

I 40 10 1 2 8 1 2 6 8 ? 6

41 11 {1} 2 8 1 2 6 8 ? 6

42 12 1 2 [9] 1 2 6 8 ? 6

43 13 1 2 9 1 2 6 17 ? 6

44 14 2 2 9 1 2 6 17 ? 6

I 45 10 2 2 9 1 2 6 17 ? 6

46 15 2 2 9 1 2 8,5 17 ? 6

47 16 2 2 9 {1} 2 {8,5} 17 ? 6

48 17 2 2 9 1 2 8,5 17 ? 14,5

49 18 2 2 9 2 2 8,5 17 ? 14,5

E 50 5 2 2 9 2 2 8,5 17 ? 14,5

51 19 2 2 9 2 2 8,5 17 7,25 14,5

52 20 2 2 9 2 2 8,5 17 {7,25} 14,5

Page 17: Capitulo 4 - Comandos de Repetição

76 Algoritmos e Programação

As linhas identificadas com E são relativas ao laço externo e as marcadas com I são

relativas ao laço interno. Note que o número de instruções executadas é bastante grande.

Isto ocorre em virtude do encadeamento dos laços, mesmo tendo usado entradas pe-

quenas (duas turmas com 3 e 2 alunos). Os custos computacionais de laços encadeados

no desempenho de algoritmos serão analisados com mais detalhes no capítulo 12.

Exercício proposto

1. Faça um algoritmo que calcule a média de todas as escolas de uma cidade. Cada

escola tem diversas turmas. Considere como entrada o número de escolas, o número

de turmas de cada escola e o número de alunos de cada turma. A média de cada

escola deve ser apresentada, além da média geral, que será o resultado da média

de todas as escolas da cidade.

4.4 Comando repitaAlém do comando enquanto, existem outras estruturas para implementar laços repetiti-

vos. O comando repita funciona de forma similar ao comando enquanto, exceto pelo

fato de que a condição de controle só é testada após a execução do bloco de comandos,

e não antes, como é o caso do comando enquanto.

Vejamos sua sintaxe:

repita <bloco de instruções>até <valor booleano>;<continuação do algoritmo>

Assim, podemos utilizar o comando repita sempre que tivermos certeza de que o bloco

de instruções será executado ao menos uma vez, sem a necessidade do teste na entrada

do bloco. Vejamos um exemplo:

4.4.1 Problema 18 (adaptação do problema 15)

Faça um algoritmo que calcule a soma dos números ímpares entre 1 e um limite superior

definido pelo usuário.

Algoritmo Soma_Ímpares_Versão2

var superior, num, soma: inteiro;início

1 soma 0;2 escreva(“Entre com o limite superior: “);3 leia(superior);4 num 1;

Page 18: Capitulo 4 - Comandos de Repetição

77Capítulo 4 • Comandos de Repetição

repita início

5 se (num resto 2 > 0) então6 soma soma + num;7 num num + 1;

fim8 até (num > superior);9 escreva(“A soma dos números ímpares é: “, soma);

fim

Pelo exemplo, podemos perceber que a condição do laço até (num > superior) é

diferente da similar no comando enquanto implementada no problema 15, enquanto (num <= superior). Isso ocorre porque, ao contrário do comando enquanto, a saída

de um laço repita ocorre quando a condição booleana se torna verdadeira. Nos laços

enquanto, a saída do laço só ocorre quando a condição se torna falsa.

Vejamos o teste de mesa considerando o limite superior como 4 (Tabela 4.3).

Tabela 4.3 – Teste de mesa para Soma_Ímpares_Versão2

Instrução Linha num superior soma1 1 ? ? 02 2 ? ? 03 3 ? [4] 04 4 1 4 05 5 1 4 06 6 1 4 17 7 2 4 18 8 2 4 19 5 2 4 1

10 7 3 4 111 8 3 4 112 5 3 4 113 6 3 4 414 7 4 4 415 8 4 4 416 5 4 4 417 7 5 4 418 8 5 4 419 9 5 4 4

Notemos que a linha do comando repita não é registrada na execução. Isso ocorre

porque na realidade o que é executado é apenas o teste de controle e o desvio do fluxo

do algoritmo dependendo do resultado do teste.

Page 19: Capitulo 4 - Comandos de Repetição

78 Algoritmos e Programação

Exercícios propostos

1. Faça a multiplicação apenas por meio de somas (utilize o comando repita).

2. Faça um algoritmo que determine se um número é primo (utilize o comando

repita).

4.5 Comando paraSe analisarmos os exemplos de utilização de laços, perceberemos que a maioria deles

tem comportamento similar. Uma situação inicial, definida antes do início do laço como

uma preparação para a sua entrada, um teste de controle para a entrada/saída do bloco

e uma instrução dentro do laço que, em algum momento, fará com que a condição de

controle seja atingida e o laço se encerre no momento oportuno.

Vejamos um exemplo:

Algoritmo Soma_Ímpares_Versão3

var inferior, superior, num, soma: inteiro;início soma 0; escreva(“Entre com o limite superior: “); leia(superior); num 1; { Situação inicial, ou preparação para a entrada no laço } enquanto (num <= superior) faça { Teste de entrada/saída } início se (num resto 2 > 0) então soma soma + num; num num + 1; { Instrução utilizada para que a condição de controle seja atingida } fimfim

O comando para procura resumir essas três características comuns à maioria das im-

plementações de laços em uma só instrução, facilitando assim a construção típica de

laços.

A sintaxe do comando para:

para (<instrução1 de preparação> [, <instrução2 de preparação> ...]; <condição1 de controle>[, <condição 2 de controle>...]; <passo para alcance da condição>) faça

<bloco de instruções><continuação do algoritmo>

Portanto, temos a separação do comando em três cláusulas: preparação, condição e

passo.

Page 20: Capitulo 4 - Comandos de Repetição

79Capítulo 4 • Comandos de Repetição

Vale citar que, quando temos mais de uma instrução de preparação (primeira cláusula),

estas são separadas por vírgula e executadas na ordem em que se encontram no comando.

Quando temos mais de uma condição de controle (segunda cláusula), os testes também

são realizados em ordem, e a condição toda é Verdadeira apenas se todas as condições

o forem. Ou seja, é equivalente a uma condição lógica ligada pelo conectivo e. Não há

como representar composição de condições ou no comando para. Nesse caso, deve-se

obrigatoriamente fazer uso dos comandos enquanto ou repita.

Algumas linguagens de programação não implementam explicitamente a terceira cláusula

(passo), e esta tem, nesses casos, um comportamento implícito sempre igual. No caso

da linguagem Pascal, por exemplo, o passo sempre é o incremento/decremento em 1 à

variável preparada na primeira cláusula. Nesses casos, em geral, o para é usado quase

que exclusivamente em algoritmos com contadores. Já a linguagem de programação C

implementa todas as cláusulas do comando para.

O comando para é executado da seguinte maneira:

1. Execute a instrução de preparação na primeira iteração do laço.

2. Execute o teste de controle. Caso seja Verdadeiro, passe para o item 3. Caso contrário,

passe para o item 6.

3. Execute o bloco de instruções.

4. Execute o passo para alcance da condição de controle.

5. Passe para o item 2.

6. Saia do laço e prossiga o algoritmo.

O comando para é equivalente à seguinte estrutura:

<instrução de preparação>enquanto (<teste de controle>) façainício <instruções> <passo>fim

Implementemos novamente o algoritmo Soma_Ímpares_Versão1 utilizando o comando

para em vez do comando enquanto:

Algoritmo Soma_Ímpares_Versão4

var superior, num, soma: inteiro;início

1 soma 0;2 escreva(“Entre com o limite superior: “);

Page 21: Capitulo 4 - Comandos de Repetição

80 Algoritmos e Programação

3 leia(superior);4 para (num 1; num <= superior; num num + 1) faça5 se (num resto 2 > 0) então6 soma soma + num;7 escreva(“A soma dos números ímpares é: “, soma);

fim

O bloco de instruções do comando para só contém uma instrução (o comando se) e,

por isso, não precisa ser delimitado pelo início/fim.

Vejamos o teste de mesa considerando o limite superior como 4 (Tabela 4.4).

Tabela 4.4 – Teste de mesa para Soma_Ímpares_Versão4

Instrução Linha num superior soma Comentários1 1 ? ? 0

2 2 ? ? 0

3 3 ? [4] 0

4 4 1 4 0 Instrução inicial

5 4 1 4 0 Teste de entrada/saída6 5 1 4 0

7 6 1 4 1

8 4 2 4 1 Passo

9 4 2 4 1 Teste de entrada/saída10 5 2 4 1

11 4 3 4 1 Passo

12 4 3 4 1 Teste de entrada/saída13 5 3 4 1

14 6 3 4 4

15 4 4 4 4 Passo

16 4 4 4 4 Teste de entrada/saída17 5 4 4 4

18 4 5 4 4 Passo

19 4 5 4 4 Teste de entrada/saída20 7 5 4 {4}

Perceba que o número de instruções executadas é praticamente igual ao número de ins-

truções executadas na implementação do mesmo algoritmo utilizando o comando repita

apresentado na seção 4.4, apesar de o número de linhas do algoritmo ser diferente.

Podemos notar que a linha 4 (do comando para) contém mais de uma instrução, sendo

representada separadamente no teste de mesa. Isso porque o comando para é uma cons-

trução diferente no que diz respeito apenas ao estilo de programação, mas internamente

seu funcionamento é igual ao do comando enquanto ou repita, e não há ganho de

Page 22: Capitulo 4 - Comandos de Repetição

81Capítulo 4 • Comandos de Repetição

desempenho ou diminuição de instruções executadas pela sua utilização. Temos apenas

uma diminuição do número de linhas do algoritmo em virtude de seu estilo compacto,

em que descrevemos três instruções em apenas uma linha.

4.5.1 Problema 19 – Calcular o somatório

Faça um algoritmo que calcule a seguinte fórmula:

�n

i = 3

(5 * i + 2)

em que n é definido pelo usuário.

Esse tipo de fórmula encaixa-se perfeitamente na estrutura do comando para. Podemos

separar:

• Instrução de preparação: i = 3

• Condição de saída: i = n

• Passo: i i + 1

Algoritmo Somatório

var i, n, somat: inteiro;início

1 escreva(“Entre com o limite superior: “);2 leia(n);3 somat 0;4 para (i 3; i <= n; i i + 1) faça5 somat somat + (5 * i + 2);

6 escreva(“O somatório �n

i = 3

(5 * i + 2) para o limite definido “, n, “ é “, somat);

fim

Exercícios propostos

1. Faça o teste de mesa para o algoritmo Somatório.

Faça os próximos algoritmos utilizando o comando para.

2. Faça a multiplicação apenas por meio de somas.

3. Faça um algoritmo que determine se um número é primo.

Page 23: Capitulo 4 - Comandos de Repetição

82 Algoritmos e Programação

4.6 Exercícios do capítulo

1. Da mesma forma que a multiplicação pode ser expressa como o resultado de várias

adições, a potenciação pode ser representada por uma série de multiplicações. Faça

um algoritmo que calcule a potenciação utilizando o operador “*”. Depois, faça o

teste de mesa para garantir que o exercício está correto.

2. Considerando que a potenciação é o resultado de várias multiplicações e que a mul-

tiplicação pode ser expressa por meio de adições, implemente um algoritmo que

realize a potenciação apenas por meio de adições.

3. Faça um algoritmo que calcule a divisão inteira de dois números, por exemplo,

10 div 3 = 3, utilizando o operador de adição ou subtração. Depois, faça o teste

de mesa para garantir que o exercício está correto.

Para auxiliar na resolução deste exercício, observe que a operação de divisão segue

o raciocínio similar ao da multiplicação, porém de forma inversa. Ou seja, o número

de vezes que se subtraindo o dividendo (operando1) pelo divisor (operando2) chegar

a 0 é o quociente procurado.

Vejamos o exemplo: 12 div 3.

Operando1: 12

Operando2: 3

Quociente: 4

Se calcularmos 12 - 3 - 3 - 3 - 3 = 0 (12 subtraído 4 vezes (quociente) por 3 é igual a 0).

Caso o quociente não seja exato, é preciso verificar que a próxima subtração terá um

resultado negativo:

13 div 3 13 - 3 - 3 - 3 - 3 = 1.

Subtraindo-se mais uma vez, teremos –2. Portanto, o resultado procurado é 4.

4. Faça um algoritmo que calcule a soma dos números primos entre 1 e 100.

5. Dada a definição de MDC: “dados dois números inteiros a e b não nulos, define-se o

máximo divisor comum (MDC) como sendo o maior inteiro que divide simultanea-

mente a e b”, faça um algoritmo que leia dois números e, a partir deles, descubra o

máximo divisor comum (MDC).

6. Dada a definição de MMC: “dados dois números inteiros a e b não nulos, define-se

o mínimo múltiplo comum (MMC) como sendo o menor inteiro positivo, múltiplo

comum de a e b”, faça um algoritmo que leia dois números e encontre o mínimo múl-

tiplo comum (MMC). Esse algoritmo deve utilizar o seguinte método para calcular o

MMC: "multiplicar os dois números e dividirpelo MDC (máximo divisor comum)".

Page 24: Capitulo 4 - Comandos de Repetição

83Capítulo 4 • Comandos de Repetição

7. Faça um novo algoritmo para o cálculo do MMC de dois números, mas que em vez

de utilizar a fatoração, parta do seguinte princípio: "o MMC é o menor número maior

ou igual ao maior dos dois números escolhidos e que é divisível pelos dois números

iniciais." Portanto, parta do maior dos dois números e verifique, dentro do laço, se o

número é o MMC testando sua divisibilidade pelos dois números.

8. Otimize o algoritmo do exercício 7 considerando que os números candidatos ao

MMC devem ser múltiplos do maior dos dois números. Portanto, teste apenas seus

múltiplos (somando não 1, mas o valor do maior dos dois números), dentro do laço

para encontrar o MMC.

9. Faça o algoritmo para a resolução do somatório a seguir, sendo n definido pelo

usuário e maior que 5:

�n

i = 5

(2 * i2+ 5 * i + 1)

10. Faça um algoritmo que encontre o n-ésimo termo da série de Fibonacci. A série de

Fibonacci é dada por:

fib(n) = fib(n - 1) + fib(n - 2) para n > 1;

Para n = 0 e n = 1, o valor é dado por definição: fib(0) = 0 e fib(1) = 1.

Exemplos:

fib(0) = 0

fib(1) = 1

fib(2) = fib(1) + fib(0) = 1 + 0 = 1

fib(3) = fib(2) + fib(1) = 1 + 1 = 2

fib(4) = fib(3) + fib(2) = 2 + 1 = 3

fib(5) = fib(4) + fib(3) = 3 + 2 = 5

fib(6) = fib(5) + fib(4) = 5 + 3 = 8

Page 25: Capitulo 4 - Comandos de Repetição

84 Algoritmos e Programação

4.7 Exemplos de programas em Pascal e C

A seguir, temos programas para facilitar a transição do pseudocódigo para linguagem de

programação. Os programas escolhidos contêm exemplos comentados dos conceitos

e notações introduzidos no capítulo. Todo programa implementado tem o seu corres-

pondente em pseudocódigo no apêndice A ou no próprio corpo do livro.

4.7.1 Programas em Pascal

4.7.1.1 Encontrar o n-ésimo termo da série de Fibonacci (exercício 10)

Faça um algoritmo que encontre o n-ésimo termo da série de Fibonacci. Para mais in-

formações sobre a série de Fibonacci, veja o exercício 10 na página 84.

Arquivo Cap_04_10.pas

program Fibonacci(Input, Output);var n, fib_menos_1, fib_menos_2, fib_N, i: integer;begin write('Digite n, para calcular o n-ésimo termo da série de Fibonacci: '); readln(n); { O conectivo 'or' corresponde ao conectivo 'ou' } if (n = 0) or (n = 1) then fib_N := n else begin fib_menos_2 := 0; { penúltimo valor } fib_menos_1 := 1; { último valor } { O comando 'for' corresponde ao comando 'para'. Em Pascal, a cláusula 'passo' é implícita } { O comando a seguir equivale a 'para (i 2; i <= n; i i + 1)' } for i := 2 to n do begin fib_N := fib_menos_1 + fib_menos_2; fib_menos_2 := fib_menos_1; fib_menos_1 := fib_N; end; end; writeln('O n-ésimo termo da série de Fibonacci é: ', fib_N)end.

4.7.1.2 Ler 100 números e retornar a soma e a média aritmética desses valores (problema 12)

Faça um algoritmo que leia 100 números e retorne a soma e a média aritmética desses

valores.

Page 26: Capitulo 4 - Comandos de Repetição

85Capítulo 4 • Comandos de Repetição

Arquivo Cap_04_prob12.pas

program Soma_media_100(Input, Output);var contador: integer; soma, media, valor: real;begin contador := 0; { Nenhuma iteração feita até aqui } soma := 0; { Ainda não foi somado nenhum valor } valor := 0; writeln('Digite 100 valores para calcular a média aritmética.');

{ O comando 'while' corresponde ao comando 'enquanto' } while (contador < 100) do begin write('Entre com um valor: '); readln(valor); soma := soma + valor; contador := contador + 1; { A cada iteração conta-se mais um } end; media := soma / contador; { Calcula a média aritmética } writeln('Soma: ', soma:18:2); writeln('Média aritmética: ', media:18:2);end.

4.7.1.3 Calcular a soma dos números ímpares entre 1 e um limite superior (problema 18)

Faça um algoritmo que calcule a soma dos números ímpares entre 1 e um limite superior

definido pelo usuário.

Arquivo Cap_04_prob18.pas

program Soma_impares(Input, Output);var superior, num, soma: integer;begin soma := 0; { ainda não foi somado nenhum valor } write('Entre com o limite superior: '); readln(superior); num := 1; { O comando 'repeat' corresponde ao comando 'repita'} { Em Pascal, o repeat não precisa da definição explícita do início/fim do bloco } repeat if num mod 2 > 0 then soma := soma + num; num := num + 1; until (num > superior); writeln('A soma dos números ímpares de 1 até ', superior, ' é: ', soma);end.

Page 27: Capitulo 4 - Comandos de Repetição

86 Algoritmos e Programação

4.7.2 Programas em C

4.7.2.1 Encontrar o n-ésimo termo da série de Fibonacci (exercício 10)

Faça um algoritmo que encontre o n-ésimo termo da série de Fibonacci. Para mais in-

formações sobre a série de Fibonacci, veja o exercício 10 na página 84.

Arquivo Cap_04_10.c

#include <stdio.h>int main(){ int n, fib_menos_1, fib_menos_2, fib_N, i; printf("Digite n, para calcular o n-ésimo termo da série de Fibonacci.\n"); scanf("%d", &n); if (n == 0 || n == 1) fib_N = n; else { fib_menos_2 = 0; /* penúltimo valor */ fib_menos_1 = 1; /* último valor */ /* O comando for corresponde ao comando "para" */ for (i = 2; i <= n; i++) { fib_N = fib_menos_1 + fib_menos_2; fib_menos_2 = fib_menos_1; fib_menos_1 = fib_N; } } printf("O n-ésimo termo da série de Fibonacci é: %d \n", fib_N); return 0;}

4.7.2.2 Ler 100 números e retornar a soma e a média aritmética desses valores (problema 12)

Faça um algoritmo que leia 100 números e retorne a soma e a média aritmética desses

números.

Arquivo Cap_04_prob12.c#include <stdio.h>int main(){ int contador; float soma, media, valor; contador = 0; /* nenhuma iteração feita até aqui */ soma = 0; /* ainda não foi somado nenhum valor */ valor = 0; printf("Digite 100 valores para calcular a média aritmética.\n");

Page 28: Capitulo 4 - Comandos de Repetição

87Capítulo 4 • Comandos de Repetição

while (contador < 100) { printf("Entre com um valor: "); scanf("%f", &valor); soma = soma + valor; contador = contador + 1; /* a cada iteração conta-se mais 1 */ } /* Calcula a média aritmética */ media = soma / contador; printf("Soma: %f\n", soma); printf("Média: %f\n", media); return 0; }

4.7.2.3 Calcular a soma dos números ímpares entre 1 e um limite superior (problema 18)

Faça um algoritmo que calcule a soma dos números ímpares entre 1 e um limite superior

definido pelo usuário.

Arquivo Capítulo_04_prob18.c

#include <stdio.h>int main(){ int superior, num, soma; soma = 0; /* ainda não foi somado nenhum valor */ printf("Entre com o limite superior.\n"); scanf("%d", &superior); num = 0; do /* O comando do/while faz a mesma função do comando repita/até */ { num = num + 1; /* se o número é ímpar */ if (num % 2 > 0) soma = soma + num; } while (num <= superior); printf("A soma dos números ímpares de 1 até %d é: %d\n", superior, soma); return 0;}