6 - Estruturas de Repetição

6.1 Introdução

Existem situações em que é necessário repetir um determinado trecho de programa um número de vezes ou até que algo aconteça. Veja os seguintes exemplos:

  1. Suponha que um usuário deseje verificar a área de um número não determinado de triângulos. O problema é que não se sabe a quantidade exata de triângulos. Se fosse implementado um programa que verificasse a área de apenas um triângulo, o usuário teria que executá-lo quantas vezes fosse necessário, saindo e entrando novamente no programa. Assim, será que é possível implementar um programa que repetisse a verificação enquanto o usuário desejasse, fazendo-lhe uma pergunta como "Deseja verificar área de outro triângulo?".
  1. Suponha que se deseje calcular a soma de idades de um número indeterminado de pessoas em que o usuário digita uma idade inválida (0 ou um número negativo) quando deseja encerrar a entrada das idades. Assim, repetem-se a entrada e o cálculo da soma, terminando quando o usuário digita uma idade inválida.

Assim, toda vez que se identifica um comportamento de repetição, seja explícito ou não, devem-se utilizar as estruturas de repetição para generalizar tal comportamento, utilizando, assim, uma correta lógica de programação. Caso o programador não utilize essas estruturas, estará repetindo trechos de códigos várias vezes, o que é trabalhoso, deselegante e muitas vezes inviável.

A linguagem C++ possui três tipos de estruturas de repetição, também chamadas de loops ou laços:

  1. for: recomendado quando há um número determinado de repetições.
  2. while: recomendado quando há um número indeterminado de repetições.
  3. do-while: também é recomendado quando há um número indeterminado de repetições, mas possui diferença em relação ao while.

Apesar de cada laço ter a sua recomendação, todo problema pode ser resolvido com qualquer laço. Existem diferenças entre eles, como na sintaxe e em seu próprio uso.

6.2 O laço for

A estrutura de repetição for é utilizada quando se sabe o número de vezes que um trecho do código deve ser repetido.

O formato geral do comando for é composto por três partes:

// Forma geral da estrutura de repetição for com apenas 1 instrução 
for (i = valor inicial; condição; passo)
  comando;
  • i = valor inicial

Atribui um valor inicial à variável i, que tem como função controlar o número necessário de repetições.
É sempre executada uma única vez antes do laço ser iniciado.

  • condição

Expressão relacional que, quando assumir valor falso, determinará o fim da repetição.

  • passo: incremento ou decremento

Altera o valor da variável de controle i, com o objetivo de, em algum momento, fazer com que a condição assuma valor falso. Essa instrução é executada, em toda iteração, imediatamente após a execução do corpo do laço.

Devem-se usar chaves se o corpo do laço tiver mais de uma instrução.

// Forma geral da estrutura de repetição for com bloco de comandos
for (i = valor inicial; condição; passo){
  comando1;
  comando2;
  ...
  comandoN;
}

Exemplo 1: Escrever os números inteiros de 1 a 10.

for (i = 1; i <= 10; i++)
   cout << i << endl;

No exemplo anterior, atribui-se à variável i inicialmente o valor 1, e depois vai sendo incrementada em uma unidade. Os comandos serão executados utilizando-se a variável i como controle, e seu conteúdo vai variar de 1 a 10. O passo indica como será a variação da variável de controle.

Esse exemplo é equivalente a:

for (i = 1; i <= 10; i = i + 1)
   cout << i << endl;

Exemplo 2: Escreva um algoritmo que imprima todos os números inteiros pares de 0 a 100.

#include <iostream>
using namespace std;
 
int main(){
  int i;
 
  for (i = 0; i <= 100; i = i + 2)
     cout << i << endl;
 
  return 0;
}

No exemplo anterior, atribui-se à variável i inicialmente o valor 0, e depois vai sendo incrementada em duas unidades.

Exemplo 3: Programa que mostra os primeiros N termos da série de Fibonacci, sendo que N é lido da entrada.

Na série de Fibonacci, o termo n é obtido pela soma dos termos n-1 e n-2, ou seja:

tn = tn-1 + tn-2

Considerando-se que o primeiro e o segundo termos tem valor 1, a série de Fibonacci é:

1, 1, 2, 3, 5, 8, 13, 21, …

#include <iostream>
using namespace std;
 
int main(){
  int N, a, b, c;
 
  cout << "Digite o numero de termos desejados: ";
  cin >> N;
 
  //Cálculo dos termos da série. O primeiro e o segundo termo são iguais a 1.
  a = 0;
  b = 1;
 
  //Imprime o primeiro termo.
  cout << b << endl;
 
  if (N ==1)
     return 0;
 
  for (int i = 2; i <= N; i++){
     //O próximo termo é igual à soma dos dois anteriores.
     c = a + b;
     a = b;
     b = c;
     cout << c << endl; }
 
  return 0;
}

Repare, no exemplo anterior, que a variável de controle i pode ser declarada dentro da estrutura, porém deixará de existir fora do comando for. Isso é devido ao escopo (conjunto de regras que indicam o uso e a validade de variáveis em um programa), que determina que as variáveis só têm validade dentro do bloco no qual são declaradas.

O teste de mesa do programa anterior pode ser visto a seguir. Considera-se que o usuário do programa digitou o número 3.

Variáveis Comparação
Linha N a b c i i<=N Saída
8 3 lixo lixo lixo não existe
11 3 0 lixo lixo não existe
12 3 0 1 lixo não existe
15 3 0 1 lixo não existe 1
20 3 0 1 lixo 2 verdadeiro
22 3 0 1 1 2
23 3 1 1 1 2
24 3 1 1 1 2
25 3 1 1 1 2 1
20 3 1 1 1 3 verdadeiro
22 3 1 1 2 3
23 3 1 1 2 3
24 3 1 2 2 3
25 3 1 2 2 3 2
20 3 1 2 2 4 falso

Exemplo 4: Programa que imprime todos os divisores de um número lido da entrada, utilizando uma função.

A função deve receber como parâmetros dois números inteiros e retornar verdadeiro se o primeiro número for divisível pelo segundo número e retornar falso, caso contrário.

#include <iostream>
using namespace std;
 
bool divisivel(int x, int y){
  if (x % y == 0)
    return true;
 
  return false;
}
 
int main(){
  int N;
 
  cout << "Digite um número: ";
  cin >> N;
 
  for (int i = 1; i <= N; i++){
     if ( divisivel(N, i) )
       cout << i << endl;
   }
 
  return 0;
}

Nota: o operador % retorna o resto da divisão inteira.

6.3 O laço while

A estrutura de repetição while é utilizada quando não se sabe o número de vezes que um trecho do algoritmo deve ser repetido, embora também possa ser utilizada quando se conhece esse número.

Essa estrutura baseia-se na análise de uma condição, de forma que a repetição será feita enquanto a condição mostrar-se verdadeira.

O formato geral do comando while é:

// Forma geral da estrutura de repetição while com apenas 1 instrução 
while (condição)
  comando;

Enquanto a condição for verdadeira, o comando será executado. Note que o nesse tipo de estrutura, o teste condicional ocorre no início.

Quando há uma única instrução no corpo do laço while, não é necessário o uso de chaves. Porém, quando há mais de uma instrução é obrigatório seu uso.

// Forma geral da estrutura de repetição while com bloco de comandos 
while (condição){
  comando1;
  comando2;
  ...
  comandoN;
}

O ciclo de teste e execução é repetido até que a expressão de teste se torne falsa (ou igual a zero). Então, o laço termina e o controle do programa passa para a linha seguinte ao laço (após o bloco de comandos).

O comando while pode substituir o comando for como no exemplo a seguir (veja o Exemplo 1 do laço for).

Exemplo 1: Escrever os números inteiros de 1 a 10.

int i = 1;
 
while (i <=10){
  cout << i << endl;
  i++;
}

Exemplo 2: Programa que lê as notas finais de N alunos e mostra o número de alunos aprovados e a média da classe.

Os alunos com nota acima de 60 serão considerados aprovados. O número de alunos da turma (N) deverá ser lido.

#include <iostream>
using namespace std;
 
int main(){
  int N, alunos, acima_60;
  float nota, soma, media;
 
  cout << "Digite a quantidade de alunos:  ";
  cin >> N;
 
  acima_60 = 0;
  soma = 0;
  alunos = 1;
 
  while (alunos <= N){
    cout << "Digite a nota do aluno numero " << alunos << endl;
    cin >> nota;
 
    soma = soma + nota;
 
    if (nota > 60)
      acima_60++;
 
    alunos++;
  }
 
  media = soma / N;
 
  cout << "Número de alunos acima de 60: " << acima_60 << endl;
  cout << "Média das notas da turma: " << media;
 
  return 0;
}

Exemplo 3: Programa para calcular a área de um triângulo, que não permite a entrada de dados inválidos.

Neste caso são considerados dados inválidos aqueles menores ou iguais a 0. Se for lido um valor inválido, a leitura terá que ser repetida.

#include <iostream>
using namespace std;
 
int main(){
  float base, altura, area;
 
  base = 0;
  while (base <= 0){
    cout << "Digite a medida da base: ";
    cin >> base;
  }
 
  altura = 0;
  while (altura <= 0){
    cout << "\nDigite a medida da altura ";
    cin >> altura;
  }
 
  area = base * altura / 2;
 
  cout << "Area = " << area;
 
  return 0;
}

Nas situações em que o teste condicional da estrutura de repetição while (que fica no início) resultar em um valor falso logo na primeira comparação, os comandos de dentro da repetição não serão executados.

6.4 O laço do-while

A estrutura de repetição do-while pode ser utilizada quando o número de repetições necessárias não é fixo. Os comandos serão repetidos até a condição assumir o valor falso.

O formato geral do comando do-while é:

// Forma geral da estrutura de repetição do-while
do {
  comando1;
  comando2;
  ...
  comandoN;
} while (condição);

O teste condicional do do-while ocorre no fim. Lembre-se de que é necessário usar ponto-e-vírgula após o fechamento de parêntese.

Exemplo 1: Escrever os números inteiros de 1 a 10.

int i = 1;
do {
  cout << i << endl;
  i++;
} while (i <=10);

Compare o exemplo anterior com o primeiro exemplo do laço for e com o primeiro exemplo do laço while.

A diferença entre a estrutura while e a estrutura do-while é que nesta última os comandos serão repetidos pelo menos uma vez, já que a condição de parada se encontra no final.

Exemplo 2: Programa para calcular a área de um triângulo, que não permite a entrada de dados inválidos.

Neste caso, são considerados dados inválidos aqueles menores ou iguais a 0. Se for lido um valor inválido, a leitura terá que ser repetida.

#include <iostream>
using namespace std;
 
int main(){
  float base, altura, area;
 
  do {
    cout << "Digite a medida da base: ";
    cin >> base;
  } while (base <= 0);
 
  do {
    cout << "\nDigite a medida da altura ";
    cin >> altura;
  } while (altura <= 0);
 
  area = base * altura / 2;
 
  cout << "Area = " << area;
 
  return 0;
}

Compare o exemplo anterior com o Exemplo 3 do laço while. Nesse exemplo, não é necessário realizar as atribuições iniciais da base e da altura, pois a leitura dos valores das variáveis ocorrerá antes do teste condicional.

6.5 Exercícios

1. Faça um programa que escreva todos os números ímpares de 1 a 100 utilizando a estrutura de repetição for. Refaça o programa utilizando as estruturas de repetição while e também do-while.

2. Faça um programa que receba várias idades, calcule e mostre a média das idades digitadas. Finalize digitando idade igual a zero.

3. Construir um programa que leia a idade de 10 pessoas e conte quantas possuem menos de 18 anos.

4. Faça um programa que leia um número inteiro e calcule e mostre a tabuada desse número. O programa deverá usar uma estrutura de repetição.

5. Crie um programa que imprima a tabela de conversão de polegadas para centímetros. Deseja-se que na tabela constem valores dede 1 polegada até 20 polegadas (lembrando que 1 polegada equivale a 2,54 centímetros).

6. Faça um programa que mostre apenas o n-ésimo termo da série de Fibonacci. O valor n será lido da entrada.

7. Faça um programa que leia um valor N inteiro e positivo, calcule e mostre o valor de E, conforme a fórmula a seguir:

E = 1 + 1/1! + 1/2! + 1/3! + … + 1/N!

8. Faça um programa que leia um número N e que indique quantos valores inteiros e positivos devem ser lidos a seguir. Para cada número lido, mostre uma tabela contendo o valor lido e o fatorial desse valor.

9. Faça um programa que receba um conjunto de valores inteiros e positivos, calcule e mostre o maior e o menor valor do conjunto. Considere que:
a) para encerrar a entrada de dados, deve ser digitado o valor zero;
b) para valores negativos, deve ser enviada uma mensagem;
c) os valores negativos ou iguais a zero não entrarão nos cálculos.

10. Faça um programa para calcular xy. Os valores de x e y serão fornecidos pelo usuário do programa. Não utilize funções pré-definidas.

11. Faça um programa que leia a idade e o sexo de um número não determinado de pessoas. A digitação de entradas termina quando a idade ou o sexo for inválido. Idade inválida é aquela negativa ou igual a zero. Sexo inválido é aquele diferente de 'f' e de 'm'. Calcule e mostre:
a) A média de idade de todas as pessoas;
b) A média de idade das mulheres;
c) A média de idade dos homens.

12. Em um campeonato de futebol existem cinco times e cada time possui onze jogadores. Faça um programa que leia a idade, o peso e a altura de cada um dos jogadores. Calcule e mostre:
a) A quantidade de jogadores com idade inferior a 18 anos;
b) A média das idades dos jogadores de cada time;
c) A média das alturas de todos os jogadores do campeonato;
d) A porcentagem de jogadores com mais de 80 quilos entre todos os jogadores do campeonato.

13. Faça um programa que apresente o menu de opções a seguir:

Menu de opções:
1. Média aritmética
2. Média ponderada
3. Sair

Digite a opção desejada.

Na opção 1: receber duas notas, calcular e mostrar a média aritmética.
Na opção 2: receber três notas e seus respectivos pesos, calcular e mostrar a média ponderada .
Na opção 3: sair do programa.

Verifique a possibilidade de opção inválida. Neste caso, o programa deverá mostrar uma mensagem.

14. Faça um programa que receba dez números inteiros e mostre a quantidade de números primos dentre os números que foram digitados. Utilize no programa uma função que retorne o valor verdadeiro se o número inteiro passado como parâmetro é primo e retorne o valor falso, caso contrário.

15. Faça um programa que leia N números inteiros e positivos e mostre o fatorial de cada um deles. Para construir esse programa, faça uma função que retorne o valor do fatorial de um número inteiro passado como parâmetro. A função deve ser utilizada para o cálculo do fatorial de cada um dos N números.

16. Elabore uma função que leia um número não determinado de valores positivos e retorne a média aritmética desses valores.

17. A prefeitura de uma cidade fez uma pesquisa entre seus habitantes, coletando dados sobre o salário e o número de filhos. Faça uma função que leia esses dados para um número não determinado de pessoas e retorne a média de salário da população, a média do número de filhos, o maior salário e o percentual de pessoas com salário inferior a R$ 380,00.

18. Crie uma sub-rotina que receba como parâmetro a altura (alt) e o sexo de uma pessoa e retorne o seu peso ideal. Para homens, deverá calcular o peso ideal usando a fórmula: peso ideal = 72.7 * alt - 58; para mulheres: peso ideal = 62.1 * alt - 44.7 .

19. Crie um programa que receba três valores (obrigatoriamente maiores que zero), representando as medidas dos três lados de um triângulo.
Elabore sub-rotinas para:

  • determinar se esses lados formam um triângulo (sabe-se que, para ser triângulo, a medida de um lado qualquer deve ser inferior ou igual à soma das medidas dos outros dois).
  • determinar e mostrar o tipo de triângulo (eqüilátero, isósceles ou escaleno), caso as medidas formem um triângulo.

Todas as mensagens deverão ser mostradas no programa principal.

20. Elabore uma função que receba como parâmetro um valor N (inteiro e maior ou igual a 1) e determine o valor da seqüência S, descrita a seguir:

S = 1 + 1/2 + 1/3 …

Bibliography
1. IZEKI, CLAUDIA AKEMI. Aprendendo Lógica com a Linguagem de Programação C++. 2007.
2. ASCENCIO, A. F. G. CAMPOS, E. A. V. Fundamentos da Programação de Computadores. Prentice Hall. 2007.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License