Post on 16-Apr-2015
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.
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
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 }
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}
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.
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
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
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
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;
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 }
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;
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
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);
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;
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
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
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;
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.
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.
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: “);
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
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.
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)".
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
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.
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.
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");
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;}