Você está na página 1de 34

Fundamentos de Programação em C: Uma Abordagem Algorítmica

Capítulo
6 Estruturas de Repetição
“ O que me preocupa não é nem o grito dos corruptos, dos violentos, dos sem carácter, dos desonestos,
dos sem ética... O que de facto me preocupa é o silêncio dos bons. "

- Martin Luther King -

As linguagens de programação modernas, possuem comandos, que permitem a


repetição uma acção ou um conjunto de acções. Essas instruções, pertencem a
classe das estruturas de repetição, e estão classificados como: comando de
repetição por contagem e comandos de repetição condicional.

Os programas que contêm comandos de repetição possuem uma terminologia


apropriada. Eles são denominados por programas iterativos. O processo de
repetição (cíclico) é denominado por laço ou ciclo e, cada laço recebe o nome
de iteração.

6.1 Repetição por Contagem


6.1.1 Comando For
O comando for deve ser utilizado quando se conhece o número de vezes que
uma acção ou um conjunto de acções deve ser executado. Este comando possui
a seguinte sintaxe:

for (Inícializar; Condição de repetição; Actualizar)


{
Bloco de comandos;
}

e carateriza-se pelos seguintes passos:


1º- Inicializar a variável de controlo;
2º- Avaliar a condição de repetição;
3º- Se a condição de repetição for verdadeira, executar o bloco de comandos e
saltar para o passo 5;
4ª- Se a condição de repetição for falsa executar o primeiro comando de estiver
depois do delimitador de fim de blocos;
5º- Actualizar a variável de controlo e voltar para o passo 2.

Em termos de linguagem algorítmica, esse comando é descrito pela sintaxe:

Estrutura de Repetição 65
Fundamentos de Programação em C: Uma Abordagem Algorítmica

para variável de inicio até fim passo incremento faça


início
Bloco de comandos;
fim

Exemplo 1: percorra os dez primeiros números inteiros positivos. Como


pretendemos gerar os números 1, 2, 3, ... ,10 temos como valor inicial o número
um; como valor final o número 10, e como incremento o número 1. O comando
que percorre esses números é descrito por:

para i de 1 até 10 passo 1 faça;

que na linguagem C é traduzido para

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

Exemplo 2: percorra os 1000 primeiros números inteiros positivos pares, ou seja,


gerar a sequência de números: 2, 4, 6, 8, 10, ... ,1000. Para este caso, temos
como valor inicial o número dois; valor final o número 1000 e como incremento
o número 2. O comando que percorre esses números é descrito por:

para i de 2 até 1000 passo 2 faça;

que na linguagem C é expresso por:

for (i = 2 ; i <= 1000 ; i = i + 2);

Exemplo 3: percorra os números ímpares menores do que 1000, mas no sentido


inverso. Para isso, basta tomar como valor inicial o número 999; valor final o
número 1 e incremento um número negativo -2.

para i de 999 até 1 passo -2;

que em C é expresso por:

for (i = 999 ; i >= 1 ; i = i - 2);

Agora, vamos introduzir através de alguns exemplos, os conceitos de somador


e de acumulador, que são de extrema importância para a programação.

Exemplo 4: desenvolva um programa para mostrar na tela, todos os números


inteiros positivos menores ou iguais a um determinado valor inteiro digitado pelo
utilizador.

Resolução: com base no método de refinamento sucessivo, uma possível


solução para este problema pode ser descrita pelos seguintes passos:

Versão 1
1- ler um número inteiro;

Estrutura de Repetição 66
Fundamentos de Programação em C: Uma Abordagem Algorítmica

2- imprimir os números inteiros de 1 até o número lido;

Pelo enunciado, temos como dados de entrada um número inteiro positivo n.


Vamos associar esse número à uma variável e relaciona-la com o seu tipo de
dados.

int n;

Estamos em condições de refinar a versão anterior com a declaração da variável


e a formalização de uma acção de leitura.

Versão 2
1- declarar n;
2- ler(n);
3- imprimir os números inteiros de 1 até n;

No próximo passo, vamos expandir a acção para imprimir os números inteiros


de 1 até n. Pretendemos apresentar na tela a seguinte sequência: 1, 2, 3, 4, …,
n. Essa sequência pode ser descrita por uma variável, denominada por i, que
tem como valor inicial o número um, valor final o número lido e incremento uma
unidade.

Versão 3
1- declarar i, n;
2- ler (n);
3- para i de 1 até n passo 1 faça
4- imprimir(i);

Como todas as linhas do algoritmo estão claras e não possuem qualquer


ambiguidade, o processo de refinamento termina e podemos codificá-lo para um
programa na linguagem C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int i, n;
printf (" \n Entre com um inteiro positivo: ");
scanf ("%d", &n);
for (i = 1 ; i <= n ; i = i + 1)
printf (" %d", i);
system("PAUSE");
return 0;
}

Vejamos em seguida uma simulação desse programa. Suponhamos sem perda


da generalidade que o utilizador digitou o número dois.

Estrutura de Repetição 67
Fundamentos de Programação em C: Uma Abordagem Algorítmica

iteração n i i <= n imprime (i)


0 2 1 1
1 2 1 1
2 3 0 2

que é interpretada por:

Inicialização (iteração 0): iniciamos a simulação com a leitura do um número


positivo dois, e atribuímos uma unidade à variável de i. Calculamos em seguida
o valor da expressão relacional 1<=2. Como o resultado dessa comparação é
verdadeiro, executamos à primeira iteração.

1ª iteração: mostramos o conteúdo da variável i e adicionamos uma unidade a


essa variável. Agora i é igual a dois. Avaliamos em seguida o valor da expressão
relacional 2<=2; Como o valor lógico dessa expressão é verdadeiro, executamos
à segunda iteração.

2ª Iteração: mostramos o conteúdo da variável i e adicionamos uma unidade a


essa variável. Agora i é igual a três. Avaliamos em seguida o valor da expressão
relacional 3<=2; Como o valor lógico dessa expressão é falso, o processo
iterativo termina e encerramos o programa.

Toda a variável que tem a propriedade de garantir o funcionamento de um ciclo


e determinar a condição para o seu término recebe o nome de contador.

Não fazem parte das boas practicas de programação alterar o valor final da
variável de controlo no interior de um comando de repetição.

Exemplo 5: dado uma turma com n estudantes, para n > 0, ler as notas de
frequência de cada estudante, calcular a sua média, e enviar uma mensagem de
erro a mostrar a sua situação académica.

Resolução: com base no método de refinamento sucessivo, uma possível


solução para este problema pode ser descrita pelos seguintes passos:

Versão 1
1- ler o número de estudantes da turma;
2- para cada estudante da turma faça;
3- inicio
4- ler as notas das provas de frequencias;
5- calcular a media;
6- imprimir a media e a mensagem;
7- fim

Pelo enunciado, temos como dados de entrada, o número de estudantes e as


notas das três provas de frequência. Como informação de saída, temos a média
final e uma mensagem a dizer que o estudante foi aprovado ou reprovado.
Vamos relacionar essas variáveis aos seus tipos de dados:

Estrutura de Repetição 68
Fundamentos de Programação em C: Uma Abordagem Algorítmica

int nAlunos, nota1, nota2, nota3;


float mediaAluno;

Estamos em condições de refinar a versão anterior com a declaração das


variáveis e a formalização das acções de leitura.

Versão 2
1- declarar nAlunos, nota1, nota2, nota3;
2- declarar mediaAluno;
3- ler (nAlunos);
4- para cada aluno da turma faça
5- inicio
6- ler (nota1, nota2, nota3);
7- calcular a média do aluno;
8- imprimir a média do aluno;
9- imprimir a mensagem
10- fim

No próximo passo, vamos escrever com mais rigor o processamento de todos os


os estudantes da turma. Para isso necessitamos uma variável que irá contar o
número de alunos processados. Essa variável possui a propriedade de um
contador, que denominaremos por i.

Versão 3
1- declarar nAlunos, nota1, nota2, nota3, i;
2- declarar mediaAluno;
3- ler (nAlunos);
4- para i de 1 até nAlunos passo 1 faça
5- inicio
6- ler (nota1, nota2, nota3);
7- calcular a média do aluno;
8- imprimir a media do aluno;
9- imprimir a mensagem;
10- fim

No próximo passo, vamos descrever com mais precisão o calculo da média e a


mensagem a notificar a situação académica. Pelo capítulo anterior, vimos que
para resolver essa questão, necessitamos de utilizar o comando condicional
composto.

Versão 4
1- declarar nAlunos, nota1, nota2, nota3, i;
2- declarar mediaAluno;
3- ler (nAlunos);
4- para i de 1 até nAlunos passo 1 faça
5- inicio
6- ler (nota1, nota2, nota3);
7- calcular mediaAluno = (nota1 + nota2 + nota3) / 3;
8- imprimir (mediaAluno);

Estrutura de Repetição 69
Fundamentos de Programação em C: Uma Abordagem Algorítmica

9- se mediaAluno >= 10 então


10- imprimir (" Aprovado");
11- senao
12- imprimir ("Reprovado");
13- fim

Como todas as linhas do algoritmo estão claras e não possuem qualquer


ambiguidade, o processo de refinamento termina e podemos codificá-lo para um
programa na linguagem C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int nAlunos, nota1, nota2, nota3, i;
float mediaAluno;
printf (" \n Entre com o total de alunos: ");
scanf ("%d", &nAlunos);
for (i = 1 ; i <= nAlunos ; i = i+1)
{
printf (" \n Entre com a primeira nota: ");
scanf ("%d",&nota1);
printf (" \n Entre com a segunda nota: ");
scanf ("%d",&nota2);
printf (" \n Entre com a terceira nota: ");
scanf ("%d",&nota3);
mediaAluno = (nota1 + nota2 + nota3) / 3.0;
printf (" \n Media = %.2f ", mediaAluno);
if (mediaAluno >= 10.0)
printf(" Aprovado ");
else
printf(" Reprovado ");
}
system("PAUSE");
return 0;
}

Fazem parte das boas prática programação escrever numa única linha o todas
as instruções do comando for.

Exemplo 6: desenvolva um programa para calcular a soma dos n primeiros


números inteiros positivos. Com base no método de refinamento sucessivo, uma
possível solução para este problema pode ser descrita pelos seguintes passos:

Versão 1
1- ler um número inteiro;
2- calcular a soma dos n primeiros inteiros positivos;
3- imprimir a soma;

Estrutura de Repetição 70
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Pelo enunciado, temos como dados de entrada um número inteiro positivo n, e


como informação de saída, a soma dos n primeiros números inteiros positivos.
Vamos associar esses dados as respectivas variáveis e relaciona-las com os
seus tipos de dados.

int n, soma;

Estamos em condições de refinar a versão anterior com a declaração das


variáveis e a formalização de uma acção de leitura.

Versão 2
1- declarar n, soma;
2- ler(n);
3- calcular a soma dos n primeiros inteiros positivos;
4- imprimir(soma);

No próximo passo, vamos expandir a acção para calcular a soma dos n primeiros
inteiros positivos. Para realizar essa acção, necessitaremos de uma variável que
vai percorrer esse intervalo. Seja i o nome dessa variável.

Versão 3
1- declarar n, i, soma;
2- ler (n);
3- para i de 1 até n passo 1 faça
4- Armazenar a soma dos números percorridos;
6- imprimir (soma);

Em ciencias de computação, toda a variável que tem a finalidade acumular os


valores de um processo de repetição, recebe o nome de acumulador

Em função desse conceito, vamos reescrever a versão anterior de forma a ficar


mais clara e intuitiva.

Versão 3
1- declarar n, i, soma;
2- ler (n);
3- para i de 1 até n passo 1 faça
4- Acumular a soma dos números percorridos;
6- imprimir (soma);

No próximo passo vamos descrever o funcionamento desse acumulador.


Facilmente se constata que a variável soma, vai gerar a seguinte sequência de
números inteiros:

1, 3, 6, 10, 15, ……

Vamos escrever uma fórmula matemática, que permita determinar o valor de


qualquer termo tendo em conta os valores dos termos anteriores. Seja si o í-
ésimo termo, então:

Estrutura de Repetição 71
Fundamentos de Programação em C: Uma Abordagem Algorítmica

s1= 1;
s2= 3 = 1 + 2 = s1 + 2;
s3 = 6 = 3 + 3 = s2 + 3
…..

Logo, para qualquer n > 1 a seguinte fõrmula é verdadeira:

sn = sn-1 + n

Com isso, estamos a dizer que o valor da n-éssina iteração pode ser obtido pela
adição do valor da (n-1)-éssima iteração mais n.

Com base nesse raciocínio vamos provar que s1 = 1. Pela formula anterior, s1 =
s0 + 1, então, s0 + 1 = 1, o que nos permite concluir que s0 = 0.

Isso mostra que o acumulador deve receber o valor zero, antes de iniciarmos o
processo de repetição.

Estamos em condições de refinar a versão anterior, com a descrição detalhada


do funcionamento do acumulador.

Versão 4
1- declarar n, i, soma;
2- ler (n);
3- inicializar soma com zeros;
4- para i de 1 até n passo 1 faça
5- calcular soma = soma + i;
6- imprimir (soma);

Fazem parte das boas prática de programação, inicializar todos os contadores


e todos os acumuladores. Essa inicialização deverá ser feita antes do
comando de repetição

Como todas as linhas do algoritmo estão claras e não possuem qualquer


ambiguidade, o processo de refinamento termina e podemos codificá-lo para um
programa na linguagem C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int n, i, soma;
printf (" \n Entre com um numero inteiro positivo: ");
scanf ("%d", &n);
soma = 0;
for (i = 1 ; i <= n ; i = i + 1)
soma = soma + i;
printf (" \n Soma dos % d primeiros numeros = %d ", n, soma);

Estrutura de Repetição 72
Fundamentos de Programação em C: Uma Abordagem Algorítmica

system("PAUSE");
return 0;
}

Vejamos em seguida a simulação desse programa. Suponhamos sem perda da


generalidade que n = 4.

iteração n i soma i <= n impressão


0 4 1 0 1
1 2 1 1
2 3 3 1
3 4 6 1
4 5 10 0 10

Exemplo 7: Dado um número inteiro positivo n. Calcular o fatorial desse número.

Resolução: Segundo a matemática elementar

1 𝑠𝑒 𝑛 = 0
𝑛! = {
1𝑥2𝑥 … 𝑥 𝑛 𝑠𝑒 𝑛 > 0

Numa primeira abordagem, a solução para este problema pode ser descrita
pelos seguintes passos:

Versão 1
1- ler o valor de n;
2- cálcular o fatorial de n;
3- imprimir o resultado;

Pelo enunciado, fazem parte dos dados de entrada, um número inteiro não
negativo, e da informação de saída, o factorial desse número. Vamos relacionar
esses dados às respectivas variáveis e aos seus dominios.

int n, fat;

Estamos em condições de refinar a versão anterior, com a declaração das


variáveis, e a formalização das acções de leitura e de impressão.

Versão 2
1- declarar n, fat;
2- ler (n);
2- cálcular o fatorial de n;
3- imprimir (fat);

No próximo passo vamos descrever com mais rigor, uma acção para calcular o
factorial de n. Por definição, se n for igual à zero, o factorial de n é igual à um.
Logo, essa acção consiste em inicializar a variável fat com o valor um. Mas, se
n for maior do que zero, esse valor será determinado pela multiplicação

Estrutura de Repetição 73
Fundamentos de Programação em C: Uma Abordagem Algorítmica

sucessiva dos números inteiros que vão de 1 a n. Isso quer dizer, que essa acção
pode ser modelada por um contador que irá percorrer esse intervalo. Vamos
modelar o comportamento desse contador, com base na seguinte sucessão
numérica.

1ª iteração 1! = 1
= 0! X 1

2ª iteração 2! = 1x 2
= 1!x 2
= 2

logo, na n-éssima iteração

n! = (n-1)! x n ∀ n > 1.

Isso que dizer que o factorial de n, para n > 1, pode ser obtido pelo calculo do
factorial de (n-1) multiplicado pelo valor de n.

Logo, estamos em condições de escrever a próxima versão.

Versão 4
1- declarar n, fat, i;
2- ler (n);
3- inicializar fat com 1;
4- para i de 1 até n passo 1 faça
5- cálcular fat = fat * i;
6- imprimir (fat);

Como todas as linhas deste algoritmo estão claras e não possuem qualquer
ambiguidade, podemos converte-lo para um programa em C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int n, i, fat;
printf (" \n Entre com um numero inteiro positivo: ");
scanf (" %d ", &n);
for ( fat = 1, i = 1 ; i<=n ; i++ )
fat *= i;
printf (" \n Fatorial = %d ", fat);
system ("PAUSE");
return 0;
}

Para terminar, vamos verificar se o programa devolve os resultados que


esperamos. Para n = 0 é óbvio que ele mostre o valor 1. Suponhamos sem perda

Estrutura de Repetição 74
Fundamentos de Programação em C: Uma Abordagem Algorítmica

da generalidade que n = 4. Pela tabela que descrevemos a seguir, o programa


mostra na tela o valor 24.

iteração n fat i i <= n


0 4 1 1 1
1 1 2 1
2 2 3 1
3 6 4 1
4 24 5 0

De facto 4! = 24. Mas o que acontece se o utilizador entrar com um número


negativo? Como essa questão não foi analizada, o programa mostra um valor
errado. Para corrigir esse erro, basta colocar um comando condicional depois da
leitura de dados. Esse comando deve mostrar uma mensagem de erro se o
utilizador entrar com esse número; no caso contrário, mostrar o valor do factorial
desse número. O programa que implementa essa condição é descrito a seguir:

6.2 Repetição Condicional


6.2.1 Comando while
O comando while deve ser utilizado quando não se conhece o número de vezes
que uma acção ou um conjunto de acções deve ser executado, e caracteriza-se
por efectuar o controlo da condição de repetição antes de executar cada iteração.
Este comendo possui a seguinte sintaxe:

Inicializar a variável de controlo;


while (condição de repetição)
{
Bloco de comandos;
Actualizar a variável de controlo;
}

A sua interpretação pode ser descrita pelos seguintes passos:


1º- Inicializar a variável de controlo;
2º- Avaliar a condição de repetição;
3º- Se a condição de repetição for verdadeira, executar o bloco de comandos,
actualizar a variável de controlo e voltar para o passo 2;
4º- Se a condição de repetição for falsa, executar o primeiro comando que estiver
depois do delimitador de fim de blocos.

Em termos de linguagem algorítmica, esse comando é descrito pela seguinte


sintaxe:

inicializar a variável de controlo;


enquanto condição de repetição for verdadeira faça
inicio
Bloco de comandos;

Estrutura de Repetição 75
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Actualizar à variável de controlo;


fim

Exemplo 1: dado um programa desenvolvido com o comando for

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int n, i, soma;
printf (" \n Entre com um numero inteiro positivo: ");
scanf ("%d", &n);
soma= 0;
for (i = 1 ; i <= n ; i = i + 1)
soma = soma + i;
printf (" \n Soma dos % d primeiros numeros = %d ", n, soma);
system ("PAUSE");
return 0;
}

vamos convertê-lo para o comando while. Por definição, sabemos que as


seguintes sentenças são verdadeiras:

Inicializar a variável de controlo: i = 1;


Condição de repetição: i <= n;
Actualizar a variável de controlo: i = i + 1;

Pelo esquema anterior:

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int n, i, soma;
printf (" \n Entre com um numero inteiro positivo: ");
scanf ("%d", &n);
soma = 0;
i = 1;
while (i <= n)
{
soma = soma + i;
i = i + 1;
}
printf (" \n Soma dos % d primeiros numeros = %d ", n, soma);
system ("PAUSE");
return 0;
}

Estrutura de Repetição 76
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Fazem parte das boas prática de programação escrever as acções do bloco de


comandos numa coluna interior aos seus delimitadores.

Vimos que o comando while, deve ser utilizado quando não conhecemos o
número de dados que iremos processar. Como garantir que chegamos ao
término desse conjunto de dados? A estratégia mais usual consiste em utilizar
um sentinela.

5.2.2 Sentinela de Início de Leitura


O sentinela de início de leitura é um número inteiro não negativo, que indica o
número de dados que iremos processar. Esse número deve ser incluído
(digitado) antes dos dados do problema. Por exemplo, para ler a altura de dez
pessoas, o utilizador deve digitar em primeiro lugar o número dez, e depois a
altura dessas pessoas. Em termos gráficos:

10 1.75 1.60 1.82 1.59 1.87 1.58 1.62 1.77 1.92 1.54

sentinela

Com essa estratégia, o comando while passa a ter um funcionamento análogo


ao comando for.

Exemplo 1: desenvolva um programa que mostra na tela os n primeiros números


inteiros positivos.

Resolução: com base no método de refinamento sucessivo, uma possível


solução para este problema pode ser descrita pelos seguintes passos:

Versão 1
1- ler o SENTINELA;
2- imprimir os números inteiros de 1 até o SENTINELA;

Pelo enunciado, temos como sentinela um número inteiro que indica quantos
números iremos processar. Seja n uma variável que armazena esse número.
Vamos relacionar essa variável ao seu tipo de dados.

int n;

Estamos em condições de refinar a versão anterior com a declaração do


sentinela e a formalização de uma acção de leitura.

Versão 2
1- declarar n;
2- ler (n);
3- imprimir os números inteiros de 1 até n;

No próximo passo vamos descrever com mais rigor a acção que mostra na tela
os números inteiros de 1 até n. Para isso, basta declarar um contador que

Estrutura de Repetição 77
Fundamentos de Programação em C: Uma Abordagem Algorítmica

começa no primeiro número inteiro positivo, termina no número n, e tem um


incremento em uma unidade. Seja i esse contador.

versão 3
1- declarar n, i;
2- ler (n)
3- inicializar i com 1;
4- enquanto i ≤ n faça
5- inicio
6- imprimir (i);
7- adicionar uma unidade a i;
8- fim

Como todas as linhas do algoritmo estão claras e não possuem qualquer


ambiguidade, o processo de refinamento termina e podemos codificá-lo para um
programa na linguagem C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int n, i;
printf (" \n Entre com o total de numeros: ");
scanf ("%d", &n);
i = 1;
while ( i <= n )
{
printf (" %d ", i);
i = i + 1;
}
system("PAUSE");
return 0;
}

5.2.3 Sentinela de Fim de Leitura


O sentinela de fim de leitura é um valor númerico ou carácter que é colocado no
fim de uma sequência de dados que pretendemos processar. Esse valor tem por
finalidade determinar o término do processo de leitura.

Que valores deveremos escolher para esse sentinela? A resposta a essa


questão depende do tipo de dados que iremos processar. Se tivermos de
processar um conjunto de números positivos, deveremos utilizar como sentinela
um número não positivo. Por exemplo, para processar um conjunto
indeterminado de alturas utilizaremos como sentinela o número real 0.0, porque
nenhuma pessoa tem essa altura. Em termos gráficos:

1.75 1.60 1.82 1.59 1.87 1.58 1.62 1.77 1.92 1.54 0.0

Estrutura de Repetição 78
Fundamentos de Programação em C: Uma Abordagem Algorítmica

sentinela

Mas, se quiséssemos processar um conjunto indeterminado de caracteres,


utilizaríamos como sentinela um carácter que não está contido nesse conjunto.
Por exemplo, para contar o número de estudantes do sexo masculino e feminino
de uma determinada universidade, devemos utilizar como sentinela um carácter
diferente de M ou F.

Não escolha como sentinela um valor que possa estar contido no conjunto de
dados que vamos processar.

Exemplo 1: Dado um conjunto indeterminado de números inteiros positivos. Calcular


o valor máximo.

Resolução: Façamos em primeiro lugar uma análise ao problema. A entrada


de dados consiste num conjunto indeterminado de números inteiros positivos.
Como não conhecemos a quantidade de números que iremos processar, e como
todos os números são positivos, faz sentido utilizar um sentinela de fim de leitura
com o valor zero.

Numa primeira abordagem, a solução deste problema pode ser descrita pelos
seguintes passos:

Versão 1
1- declarar SENTINELA = 0;
2- ler o primeiro número;
3- enquanto número for diferente do SENTINELA faça
4- calcular o maior elemento;
5 - imprimir resultado;

Pelo enunciado, fazem parte dos dados de entrada um conjunto indefenido de


números inteiros positivos, e da informação de saída o maior valor. Vamos
relacionar esses dados às respectivas variáveis e aos seus domínios.

int dado, maior;

Estamos em condições de refinar a versão anterior com a declaração das


variáveis e a formalização de um acção de leitura e de impressão.

Versão 2
1- declarar SENTINELA = 0;
2- declarar dado, maior;
3- ler (dado);
4- enquanto dado ≠ SENTINELA faça
3- calcular o maior elemento;
4 - imprimir ( maior);

Estrutura de Repetição 79
Fundamentos de Programação em C: Uma Abordagem Algorítmica

No próximo passo vamos tornar o processo iterativo finito, com a leitura dos
próximos números inteiros. Observe que na versão anterior lemos apenas o
primeiro dado do conjunto.

Versão 3
1 - declarar SENTINELA = 0;
2- declarar dado, maior;
3- ler (dado);
4- enquanto dado ≠ SENTINELA faça
5- inicio
6- calcular o maior elemento;
7- ler (dado);
8- fim
9- imprimir (maior);

No próximo passo vamos verificar se o conteúdo da variável dado satisfaz as


condições do problema. Essa validação consiste em verificar se o conteúdo de
dado é um número positivo.

Versão 4
1 - declarar SENTINELA = 0;
2- declarar dado, maior;
3- ler (dado);
4- enquanto dado ≠ SENTINELA faça
5- inicio
6- se dado <= 0 então
7- imprimir ("Erro: Numero não positivo");
8- senão
9- calcular o maior elemento;
10- ler (dado);
11- fim
12- imprimir (maior);

No próximo passo vamos descrever um método para calcular o maior elemento.


Esse método baseia-se na seguinte estratégia. Antes de iniciarmos o ciclo,
vamos armazenar na variável maior, o maior inteiro menor do que qualquer
elemento do conjunto. Em cada iteração, vamos comparar o conteúdo dessa
variável, com o conteúdo do dado que foi lido. Se o conteúdo do dado for maior
do que o conteúdo dessa variável, armazenamos o conteúdo do dado na
variável, no caso contrário não fazemos nada.

Versão 4
1- declarar SENTINELA = 0;
2- declarar dado, maior;
3- inicializar maior com zeros;
3- ler (dado);
4- enquanto dado ≠ SENTINELA faça
5- inicio

Estrutura de Repetição 80
Fundamentos de Programação em C: Uma Abordagem Algorítmica

6- se dado <= 0 então


7- imprimir ("Erro: Numero não positivo");
8- senão se dado > maior então
10- armazenar em maior o dado;
11- ler (dado);
12- fim
13- imprimir (maior);

Como todas as linhas deste algoritmo estão claras e não possuem qualquer
ambiguidade, podemos traduzi-lo para um programa em C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
#define SENTINELA 0 /* valor do sentinela de fim de leitura */
int main()
{
int maior = 0, dado;
printf(" \n Entre com um numero positivo: ");
scanf(" %d ", &dado);
while (dado != SENTINELA)
{
if (dado <= 0)
printf ("Erro: Numero não positivo");
else if (maior < dado)
maior = dado;
printf (" \n Entre com outro numero positivo: ");
scanf(" %d ", &dado);
}
printf(" \n Maior valor sequencia = %d \n ",maior);
system("PAUSE");
return 0;
}

Vejamos se este programa devolve os resultados que esperamos. Dado o


conjunto {10, 15, 11, 23, 17, 18, 22}. Vamos adicionar a esse conjunto o sentinela
de fim de leitura, então, o nosso conjunto passa a ser igual a {10, 15, 23, 17, 18,
22, 0}. A simulação deste algoritmo é descrita pela seguinte tabela.

Iteração maior dado maior < dado sentinela dado > sentinela
0 0 10 0 1
1 10 15 1 1
2 15 11 1 1
3 23 0 1
4 23 17 1 1
5 18 0 1
6 22 0 1
7 0 0

De facto, o maior elemento é o número 23.

Estrutura de Repetição 81
Fundamentos de Programação em C: Uma Abordagem Algorítmica

5.3 Utilização de Flag’s


Existem muitos problemas computacionais cuja solução baseia-se na utilização
de variáveis booleanas ou flag's. Inicialmente essas variáveis devem armazenar
um determinado valor lógico. Mas, quando ocorrer algum evento elas mudam
para o valor lógico oposto e mantêm-se nesse estado até ao término do
programa.

Exemplo 1: desenvolva um programa para ler uma sequência com n números


inteiros digitados pelo utilizador, verificar se essa sequência possui pelo menos
um número negativo.

Resolução: vamos analisar em primeiro lugar os dados do problema. Como


conhecemos a quantidade de números que iremos processar, devemos utilizar
como sentinela de início de leitura esse valor.

O algoritmo propriamente dito, consiste em atribuir o valor lógico verdadeiro a


uma flag antes de iniciarmos a leitura dos dados. Lembre-se que o sentinela não
faz parte dessa sequência. Em seguida, processar a sequência de números. Em
cada ciclo, ler um número inteiro e armazenar na flag o valor lógico falso se ele
for negativo. Ao terminar o processamento, verificar o conteúdo da flag. Se ela
for verdadeira todos os números são positivos, no caso contrário, temos pelo
menos um número negativo.

Como exercício, convidamos o leitor a utilizar a metodologia de refinamento


sucessivo para implementar um algoritmo que resolva essa estratégia.
Apresentaremos apenas o correpondente programa em C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int ehPositivo, i, n, numero;
printf (" \n Entre com a quantidade de numeros a ler: ");
scanf (" %d ", &n);
ehPositivo = 1; /* activação da flag */
i = 1;
while ( i <= n )
{
printf (" \n Entre com um numero inteiro: ");
scanf (" %d ", &numero);
if ( numero < 0 )
ehPositivo = 0; /* desativação da da flag */
i = i + 1;
}
if ( ehPositivo == 1 )
printf (" \n Todos os numeros são positivos ");
else
Estrutura de Repetição 82
Fundamentos de Programação em C: Uma Abordagem Algorítmica

printf (" \n Temos pelo menos um numero negativo ");


system ("PAUSE");
return 0;
}

Será que esse programa devolve os valores que esperamos? Para responder a
essa questão, vamos fazer uma simulação do programa com dados reias.

a) Suponhamos sem perda da generalidade que temos como dados de entrada


a seguinte sequência:

56 72 -21 45 -8

Como vamos utilizar um sentinela de início de leitura, teremos como dados de


entrada a seguinte sequencia:

5 56 72 -21 45 - 8

sentinela

Pela tabela que mostramos em seguida, o programa mostra na tela a mensagem:

Temos pelo menos um numero negativo

iteração n num ehPos i i <= n num < 0 ehPos = 1


0 5 1 1 1
1 56 2 1 0
2 72 3 1 0
3 -21 0 4 1 1
4 45 5 1 0
5 -8 0 6 0 1
1

Como ehPositivo = 1, o programa mostra na tela a mensagem:

Temos pelo menos um numero negativo

Mas o que acontece se tivermos como dados de entrada uma sequencia de


números positivos? A título de exercício solicitamos que o leitor faça a simulação
do programa para o seguinte conjunto de dados {5, 6, 2, 56, 21, 32, 4}.

Exemplo 2: desenvolva um programa para ler uma sequência de números


inteiros não negativos, e suspender o processo de leitura quando o utilizador
digitar o primeiro número negativo.

Resolução : vamos mais uma vês, vamos analisar os dados do problema. Como
não conhecemos a quantidade de números que iremos processar, e como todos

Estrutura de Repetição 83
Fundamentos de Programação em C: Uma Abordagem Algorítmica

os números são positivos, faz sentido utilizar um sentinela de fim de leitura com
o valor zero.

O algoritmo própriamento dito, baseia-se em utilizar uma flag que inicialmente


recebe o valor lógico falso. Em seguida vamos processar a sequência de
números. Em cada ciclo, ler um número e verificar se ele é menor do que zero.
Se essa condição for verdadeira, alterar o conteudo dessa flag para verdadeiro.
Como no próximo ciclo a condição de repetição é falsa o processo de leitura
termina. Essa estratégia é descrita pelo seguinte programa.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int terminou, num;
terminou = 0;
while ( terminou == 0 )
{
printf (" \n Entre com um numero inteiro: ");
scanf (" %d ", &num);
if ( num < 0 )
terminou = 1;
}
system("PAUSE");
return 0;
}

A título de exercício solicitamos que o leitor faça a simulação do programa para


o seguinte conjunto de dados {5, 6, 2, -56, 21, 32, 4}.

Exemplo 3: dado um conjunto indeterminado de números inteiros positivos.


Calcular o valor máximo.

Resolução: este exemplo, foi resolvido na secção anterior cutilizando para o


efeito, um sentinela de fim de leitura, Agora vamos escrever um programa
equivalente, utilizando uma flag.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
#define SENTINELA 0 /* valor do sentinela de fim de leitura */
int main()
{
int maior = 0, dado, terminou = 0;
printf(" \n Entre com um numero positivo: ");
while (terminou == 0)
{
scanf("%d",&dado);
if (dado == SENTINELA)
terminou = 1;

Estrutura de Repetição 84
Fundamentos de Programação em C: Uma Abordagem Algorítmica

else
}
if (dado <= 0)
printf ("Erro: Numero não positivo");
else if (maior < dado)
maior = dado;
printf (" \n Entre com outro numero positivo: ");
}
}
printf (" \n Maior valor sequencia =%d \n ",maior);
system("PAUSE");
return 0;
}

5.4 Comando de Interrupsão de Ciclo


A linguagem C possui um comando que permite encerrar um ciclo. Este comando
pertence a classe de comandos de interrupção de ciclos e possui a seguinte
sintaxe:

break;

O comando break deve ser colocado no interior do corpo de um comando de


repetição. Ao ser acçionado, este comando força a saída do laço que o contêm
e desvia o fluxo do programa para a primeira instrução que estiver depois do
delimitador de blocos.

Em termos de linguagem algorítmica, esse comando é descrito pela seguinte


sintaxe

abandonar;

Exemplo 1: desenvolva que dado uma sequência de números inteiros não


negativos, suspender o processo de leitura quando o utilizador digitar o primeiro
número negativo.

Resolução: na secção anterior desenvolvemos esse programa utilizando uma


flag, agora vamos desenvolvê-lo com o comando break.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int num;
while (1)
{
printf (" \n Entre com um numero inteiro: ");
scanf (" %d ", &num);
if ( num < 0) break; /* se activado força a saída do laço */
Estrutura de Repetição 85
Fundamentos de Programação em C: Uma Abordagem Algorítmica

}
system("PAUSE");
return 0;
}

A instrução while (1) gera um loop infinito, e pode ser traduzida para a linguagem
algorítmica, pela seguinte sentença:

repetir infinitamente

Se tivermos vários laços aninhados, o comando break afecta apenas o laço


que o contêm e os laços interiores.

Exemplo 2: desenvolva um programa para ler um número indeterminado de


estudantes, mostrar as suas médias e no final a média da turma. Para qualquer
estudante, ler o seu número e as notas que este obteve nas três provas de
frequência.

Resolução: como não conhecemos o número de estudantes da turma, e como


o número de qualquer estudante é positivo, faz sentido utilizar um sentinela de
fim de leitura com o valor zero.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int nAluno, nota1, nota2, nota3, totalAlunos;
float mediaAluno, mediaClasse, totalMediaClasse;
totalMediaClasse = 0.0;
totalAlunos = 0;
while (1)
{
printf (" \n Entre com numero do aluno: ");
scanf ("%d", &nAluno);
if (numeroAluno = 0) break;
printf (" \n Entre com a primeira nota: ");
scanf ("%d",&nota1);
printf (" \n Entre com a segunda nota:");
scanf ("%d", &nota2);
printf (" \n Entre com a terceira nota:");
scanf ("%d", &nota3);
mediaClasse = (nota1 + nota2 + nota3)/3.0;
printf ("\n numero = %d media = %.2f ", nAluno, mediaAluno);
if ( mediaAluno >= 10.0 )
printf (" aprovado ");
else
printf (" reprovado ");
totalMediaClasse = totalMediaClasse + mediaClasse;
totalAlunos = totalAlunos + 1;

Estrutura de Repetição 86
Fundamentos de Programação em C: Uma Abordagem Algorítmica

}
mediaClasse = totalMediaAlunos/totalAlunos;
printf ("\n Media da classe %.2f ", mediaClasse);
system ("PAUSE");
return 0;
}

Observe que apôs a linha que contêm o comando break, não é necessário
utilizar a instrução else. Quando essa linha for activada, o fluxo do programa
será desviado para a primeira linha que estiver depois do delimitador de blocos,
e o programa calculará em seguida, a média da classe, mostrará essa media na
tela, e será encerrado.

Como o comando break viola os princípios da programação estruturada


aconselhamos a utiliza-lo em situações que este torne o programa mais legível
e mais fácil de compreender.

5.5 Operador de Incremento e Decremento


O operador incremento e decremento não existem em muitas linguagens de
programação. Mas são de extrema importância para compactação de código na
linguagen C. Por exemplo, o comando de atribuição de valor:

num = num + 1;

pode ser abreviado para

num ++;

ou para

++num;

Um aspecto muito importante é que estas abreviações, podem ser utilizados


como prefixos ou sufixos, mas expressões. Porém, a expressão ++n incrementa
uma unidade antes de utilizar o valor de n, enquanto a expressão n++ incrementa
uma unidade depois do conteúdo dessa variável ter sido utilizado. Isso quer
dizer, que num determinado contexto, o resultado de ++n e n++ podem ser
diferentes. Por exemplo, suponhamos que a variável n possua o valor 5, a
expressão:

x = n++;

consiste em

x = n;
n = n+1;

e atribui a x o valor cinco. Ao passo que a expressão


Estrutura de Repetição 87
Fundamentos de Programação em C: Uma Abordagem Algorítmica

x = ++n;

consiste em

n = n+1;
x = n;

e atribui a x o valor seis. Em ambos os casos, n passa a armazenar o valor seis.

Os operadores de incremento e decremento só podem ser aplicados a variáveis.


Uma expressão do tipo:

x = ( i + 1) ++ ;

é inválida.

5.6 Constantes Simbólicas


Uma outra forma de definir uma constante na linguagem C consiste em utilizar a
directiva de pré-processamento define que possui a seguinte sintaxe:

#define identificador valor

Com esta directiva, o pré-compilador substitui todas as ocorrências desse


identificador por esse valor durante o processo de compilação. Por exemplo:

#define PI 3.1415
.
.
printf (" Calculo da area:");
.
.
x = PI * raio*raio;

A cadeia de caracteres "Calculo da area" não será afectada. Não há


substituições dentro da cadeia de caracteres, nem substituições dentro de
comentários. Após o pré-processamento esse segmento de código será
transformado em:

#define PI 3.1415
...

printf(" Calculo da area :");


...
x = 3.1415 * raio*raio;

As principais diferenças entre constantes e constantes simbólicas podem ser


sintectizadas nos seguintes pontos:

Estrutura de Repetição 88
Fundamentos de Programação em C: Uma Abordagem Algorítmica

- Uma constante necessita de um espaço de memória para guardar à informação


enquanto numa constante simbólica isso não acontece. O seu valor é substituído
no programa durante a fase de pré-processamento.

- Uma constante é uma palavra reservada da linguagem C enquanto uma


constante simbólica é declarada como uma directiva de pré-processamento, ou
seja, não é um comando dessa linguagem.

Apresentamos a seguir dois programas equivalentes. O da esquerda com a


declaração de uma constante e o da direita com uma constante simbólica.

#include <stdio.h> #include <stdio.h>


#include <stdlib.h> #include <stdlib.h>
int main() #define PI 3.1415
{ int main()
const float pi = 3.1415; {
int raio; int raio;
float area; float area;
printf (" Entre o raio: "); printf (" Entre o raio: ");
scanf (" %d ",&raio); scanf (" %d ",&raio);
area = pi*(raio*raio); area = PI*(raio*raio);
printf (" \n Area %.2f \n", area); printf (" \n Area %.2f \n ", area);
system ("PAUSE"); system ("PAUSE");
return 0; return 0;
} }

Embora não seja obrigatório tornou-se padrão de programação na linguagem


C escrever as constantes simbólicas em letras maiúsculas.

Fazem parte das boas practicas de programação, utilizar letras maiúsculas


para as constantes simbólicas. Dessa forma, as constantes destacam-se no
programa e o programador não as confunde com outras variáveis.

5.7 Inicialização Automática de Variáveis


A inicialização automatica de variáveis é outra facilidade da linguagem C para a
compactação de código. Ela é aplicada no instante da declaração das variáveis.
Por exemplo:

int soma, multiplicacao;


soma = 0;
multiplicacao = 1;

pode ser escrito como:

int soma = 0, multiplicacao = 1;

Estrutura de Repetição 89
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Fazem parte das boas prática de programação inicializar as variáveis no


instante da declaração. Essa práctica torna os programas mais eficiêntes.

5.8 Operador de Atribuição Composto


O operador de atribuição composto é mais uma facilidade da linguagem C para
a compactação de código. Ele é aplicado nas operações de atribuição de valor
quando à variável do lado esquerdo do sinal de atribuição também aparece no
lado direito. Por exemplo:

i = i + 2;

pode ser escrito como:

i +=2;

Por analogia essa propriedade pode ser aplicada aos seguintes operadores: -=,
*=, /= e %=.

Fazem parte das boas prática de programação a utilização do operador de


atribuição composto, porque este acelera o processo de compilação.

Para consolidar os conhecimentos, vejamos um exemplo ilustractivo. Um


número positivo n é perfeito se for igual a soma de seus divisores positivos
próprios (exclui-se ele mesmo). Por exemplo, o número 6 é um número perfeito,
porque:

6 = 1 + 2 + 3.

O próximo número perfeito é 28 porque

28 = 1 + 2 + 4 + 7 + 14.

Apresentamos em seguida dois programas equivalêntes que resolvem esse


problema.

#include <stdio.h> #include <stdio.h>


#include <stdlib.h> #include <stdlib.h>
int main() int main()
{ {
int num = 1, soma = 0, n; int num = 1, soma = 0, n;
printf ("\n Entre com um numero:"); printf ("\n Entre com um numero");
scanf ("%d",&n); scanf (" %d",&n);
while ( num < n ) while ( num < n )
{ {
if ( n%num == 0 ) if ( n%num ==0 )
soma = soma + num; soma += num;
num ++; num ++;
} }

Estrutura de Repetição 90
Fundamentos de Programação em C: Uma Abordagem Algorítmica

if ( soma == n ) if ( soma == n )
printf (" Numero perfeito "); printf ("Numero perfeito ");
else else
printf (" Numero nao perfeito "); printf (" Numero nao perfeito ");
system ("PAUSE"); system ("PAUSE");
return 0; return 0;
} }

A compactação de código não melhora a legebilidade do programa, mas é um


padrão da programação na linguagem C

5.9 Operador Vírgula


O operador vírgula tem por finalidade encadear um conjunto de acções. Por
exemplo:

pos = 0, ind = 1;

é equivalente à

pos = 0;
ind = 1;

Este operador é muito utilizado para a compactação de código. Apresentamos a


seguir dois programas equivalentes. O da esquerda sem o operador vígula e o
da direita com esse operador.

#include <stdio.h> #include <stdio.h>


#include <stdlib.h> #include <stdlib.h>
int main() int main()
{ {
int fat = 1, i, n; int fat, i, n;
printf (" \n Entre com numero:"); printf (" \n Entre com numero:");
scanf (" %d ",&n); scanf (" %d ",&n);
for ( i = 1 ; i <= n ; i ++ ) for ( fat = 1, i = 1 ; i <= n ; i ++ )
fat *= i; fat *= 1;
printf (" \n Fatorial = %d ", fat); printf (" \n Fatorial = %d ", fat);
system ("PAUSE"); system ("PAUSE");
return 0; return 0;
} }

5.10 Fórmulas Recorrêntes


Existem alguns problemas de computação científica, cuja solução baseia-se na
utilização de fórmulas recorrêntes.

Estrutura de Repetição 91
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Entendemos por fórmula recorrênte, uma relação entre os termos consecutivos


de uma sucessão numérica, que nos permite obter o próximo termo, tendo em
conta os valores dos termos anteriores. Um exemplo clássico é a sucessão
(sequência) de Fibonacci que é definida pela fórmula:

1 se i = 1
Fi = { 1 se i = 2
Fi−1 + Fi−2 se i > 2

e descrita pela seguinte sequência.

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, .....

Exemplo 1: desenvolva um programa para ler dois números inteiros e calcular


𝑥 𝑦 ∀𝑦 ≥ 0.

Resolução: suponhamos sem perda da generalidade que x é igual a dois. Pela


matemática elementar, sabemos que:

para y = 0 , 20 = 1

para y = 1 , 21= 2
=1x2
= 20 x 2
=2

para y = 2 , 22 = 2 x 2
= 21x 2
=4

para y = 3 , 23= 2x2x2


=4x2
= 22x2
=8

logo podemos concluir que se y = n

2n = 2(n -1) x 2

Então a fórmula recorrente para calcular a potênçia de um número inteiro x com


um expoente inteiro não negativo y, é determinada por:

1 se y = 0
xy = {
x (y−1) x se y > 0

Agora, vamos desenvolver um algoritmo, que utiliza um comando de repetição,


para modelar essa fórmula. Numa primeira abordagem, esse algoritmo pode ser
descrito pelos seguintes passos:

Estrutura de Repetição 92
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Versão 1
1- ler os números inteiros x e y;
2- calcular a potençia de x elevado a y;
3- imprimir o resultado;

Pelo enunciado temos como dados de entrada dois números inteiros e como
informação de saída, o valor da potênçia desses números. Vamos relaciona-los
às respectivas variáveis e aos seus domínios.

int x, y, pot;

Estamos em condições de declarar as variáveis e as acções de leitura e


impressão dos dados.

Versão 2
1- declarar x, y, pot;
2- ler (x, y);
3- calcular a potência de x elevado a y;
4- imprimir (pot);

No próximo passo vamos escrever com mais detalhe o cálculo da potênçia de x


elevado a y. Pela fórmula recorrênte, se y for igual a zero, a potência é igual a 1,
logo, essa operação consiste em armazenar na variável pot o valor 1. Mas se y
for maior do que 1, esse valor será igual a potência de y-1 vezes o valor x, logo
essa operação consiste em percorrer os números inteiros de 1 até y, e para cada
número, calcular o valor da sua potência.

Versão 3
1- declarar x, y, pot;
2- ler (x, y)
3- inicializar pot com 1;
4- percorrer os numeros de 1 até y
5- calcular a potênçia desse número;
6- imprimir(pot);

No próximo passo vamos descrever com mais rigor a acção para percorrer os
números inteiros de 1 até y e calcular o valor da sua potencia. Essa acção
consiste em declarar um contador que irá percorrer esse intervalo. Em cada
iteração, multiplicar o valor da iteração anterior, que está na variável pot, pelo
valor de x (base da potência).

Versão 4
1- declarar x, y, pot, i;
2- ler (x, y)
3- inicializar pot com 1;
4- para i de 1 até y passo 1 faça
5- calcular pot = pot * x;
6- imprimir(pot);

Estrutura de Repetição 93
Fundamentos de Programação em C: Uma Abordagem Algorítmica

Como todas as linhas do algoritmo estão claras e não possuem qualquer


ambiguidade, o processo de refinamento termina e podemos codificá-lo para um
programa na linguagem C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
int main()
{
int x, y, pot, i;
printf (" \n Entre com a base da potencia: ");
scanf ("%d", x);
printf (" \n Entre com o expoente da potencia:");
scanf ("%d", y);
for ( pot = 0 , i = 1 ; i <= y ; i++)
pot = pot * x;
printf (" \n Valor de %d elevado a %d igual a %d ", x, y, pot);
system ("PAUSE");
return 0;
}

Exemplo 2:

5.11 Comando de Repetição Aninhado


No capítulo anterior, vimos que era possível construir programas com um
comando condicional dentro de num outro comando condicional. Apesar de não
termos enunciado de forma explicita uma regra de utilização, acreditamos que o
leitor tenha entendido que o comando condicional mais interno está
completamente encaixado (aninhado) no comando condicional externo. Essa
regra também aplica-se aos comandos de repetição.

Exemplo 1: Uma das formas de medir o índice de obesidade de uma população


é calcular o peso médio de pessoas da mesma idade. Por exemplo, o peso médio
das pessoas que têm 18 anos, das que têm 30 anos, etc. Os pesos são
agrupados por idades. Não há limite para o número de grupos nem para o
número pesos dentro de cada grupo. Cada peso é um valor inteiro positivo. Para
facilitar a construção do programa, supomos que os dados estão organizados da
seguinte forma:

Idade do primeiro grupo


Peso
… (peso das pessoas do 1º grupo)

Peso
-1
Idade do 2º grupo
Peso

Peso

Estrutura de Repetição 94
Fundamentos de Programação em C: Uma Abordagem Algorítmica

-1

Idade do último grupo
Peso
….
Peso

Resolução: Pelo enunciado, percebe-se que a forma de organização dos dados,


consiste na idade de um grupo, seguido de um conjunto finito de pesos desse
grupo, delimitado pelo valor -1. Como não conhecemos quantas grupos iremos
processar, faz sentido utilizar um sentinela de fim de leitura com o valor 999.

Também gostavamos de salientar que na resoluçao deste exercício estamos a


supor que o utilizador não comete erros a digitar os dados de entrada.

Numa primeira abordagem, a solução para este problema pode ser descrita
pelos seguintes passos:

Versão 1
1- ler a idade do grupo;
2- enquanto mesmo grupo faça
3- inicio
4- calcular a média da idade;
5- imprimir a idade do grupo e seu peso médio;
6- fim

Pelo enunciado, temos como dados de entrada, idade do grupo e o peso das
pessoas desse grupo. Como informação de saída temos a média dos pesos das
pessoas de cada grupo e a idade do grupo. Mas, para calcular a média dos pesos
das pessoas de um grupo, devemos dividir o total do peso das pessoas desse
grupo pelo número de pessoas existentes no grupo. Isto permite-nos declarar as
seguintes variáveis:

int idade, peso, totalPesoGrupo, totalPessoasGrupo;

Também podemos declarar, as seguintes constantes:

# define SENTINELAIDADE 999


# define SENTINELAPESO -1

Pela forma de organização dos dados, facilmente percebemos que temos duas
estruturas de repetição aninhadas. A mais externa, processa todos os grupos,
enquanto a mais interna, processa as pessoas do mesmo grupo. Vamos refinar
a versão anterior, com a declaração das variáveis, constantes e detalhar o
funcionamento da estrutura de repetição mais externa.

Versão 2
1- declarar SENTINELAIDADE 999;
2- declarar SENTINELAPESO -1;

Estrutura de Repetição 95
Fundamentos de Programação em C: Uma Abordagem Algorítmica

3- declarar idade, peso, pesoTotalGrupo, totalPessoasGrupo;


4- ler (idade);
5- enquanto (idade < SENTINELAIDADE) faça
6- início
7- calcular idade média do grupo;
8- imprimir a idade e o peso médio do grupo;
9- ler (idade);
10- fim

No próximo passo vamos escrever com mais detalhe as acções para calcular a
idade média do grupo. Calcular a idade média consiste em dividir a soma dos
pesos das pessoas do mesmo grupo pela quantidade de pessoas desse grupo.
Isso quer dizer que necessitamos de processar, todas as pessoas do mesmo
grupo, e com essa acção, descrever o funcionamento da estrutura de repetição
mais interna.

Versão 3
1- declarar SENTINELAIDADE 999;
2- declarar SENTINELAPESO -1;
3- declarar idade, peso, pesoTotalGrupo, totalPessoasGrupo;
4- ler (idade);
5- enquanto (idade < SENTINELAIDADE) faça
6- inicio
7- enquanto pessoas da mesma idade faça
8- inicio
9- contar o número de pessoas;
10- calcular o peso total;
11- fim
12- imprimir a idade e o peso médio desse Grupo;
13- ler (idade);
14- fim

No próximo passo vamos descrever a acção pessoas da mesma idade. Pelo


enunciado, sabemos que as pessoas da mesma idade têm o seu peso em
posições consecutivas e delimidados por -1.

Versão 4
1- declarar SENTINELAIDADE 999;
2- declarar SENTINELAPESO -1;
3- declarar idade, peso, pesoTotal, totalPessoas;
4- ler (idade);
5- enquanto (idade < SENTINELAIDADE) faça
6- inicio
7- ler peso da primeira pessoa do grupo;
8- enquanto (peso ≠ SENTINELAPESO) faça
9- inicio
10- contar o número de pessoas;
11- calcular o peso total;
12- ler peso da próxima pessoa do grupo;

Estrutura de Repetição 96
Fundamentos de Programação em C: Uma Abordagem Algorítmica

13- fim
14- imprimir a idade e o peso médio desse grupo;
15- ler (idade);
16- fim

No próximo passo vamos definir com mais rigor as acções para contar o número
de pessoas, calcular o peso total e o peso medio de um grupo. Essas acções
serão obtidas pelo contador que retrata o total de pessoas do mesmo grupo, o
acumulador que retrata o total do peso das pessoas desse grupo, e a fórmula
matemática para apurar o peso médio desse grupo.

Versão 5
1- declarar SENTINELAIDADE 999;
2- declarar SENTINELAPESO -1;
3- declarar idade, peso, pesoTotalGrupo, totalPessoasGrupo, pesoMedio;
4- ler (idade);
5- enquanto (idade < SENTINELAIDADE) faça
6- inicio
7- ler (peso);
8- armazenar em totalPessoasGrupo o valor 0;
9- armazenar em pesoTotalGrupo o valor 0;
10- enquanto (peso ≠ SENTINELAPESO) faça
11- inicio
12- adicionar ao totalPessoasGrupo uma unidade;
13- adicionar ao pesoTotalGrupo o peso da pessoa;
14- ler(peso);
15- fim
16- calcular pesoMedio = pesoTotalGrupo/totalPessoasGrupo;
17- imprimir ( idade, pesoMedio);
18- ler (idade);
19- fim

Como todas as linhas deste algoritmo estão claras e não possuem qualquer
ambiguidade, podemos traduzi-lo para um programa em C.

#include <stdio.h> /* incluir as funções scanf() e printf() */


#include <stdlib.h> /* incluir a função system() */
#define SENTINELAIDADE 999 /* sentinela de fim de grupo de idade */
#define SENTINELAPESO -1 /* sentinela de fim de processamento */
int main()
{
int pesoTotalGrupo= 0, totalPessoasGrupo= 0, idade, peso;
printf (" \n Entre com a idade do grupo: ");
scanf (" %d ", &idade);
while (idade < SENTINELAIDADE)
{
printf (" \n Entre com o peso da primeira pessoa: ");
scanf (" %d ", &peso);
while (peso != SENTINELAPESO)

Estrutura de Repetição 97
Fundamentos de Programação em C: Uma Abordagem Algorítmica

{
totalPessoasGrupo ++;
pesoTotalGrupo += peso;
printf (" \n Entre com o peso da proxima pessoa:");
scanf (" %d ", &peso);
}
printf (" \n Idade do Grupo: %d “, idade);
printf (" Peso medio: %.2f ",pesoTotalGrupo/totalPessoasGrupo);
printf (" \n Entre com a idade do grupo: ");
scanf (" %d ", &idade);
}
system("PAUSE");
return 0;
}

5.12 Funções Utilitárias


O arquivo cabeçalho-padrão <stdlib.h> da biblioteca-padrão definida pela ANSI,
possui um conjunto de funções de utilização geral. Veremos a seguir as funções
mais utilizadas.

int rand(void); retorna um número inteiro aleatório entre 0 e RAND_MAX. Por


exemplo, a expressão rand( )%n retorna um número inteiro entre 0 à n-1.

void srand(int s); Inicia a geração de um número inteiro aleactório. Apôs a


chamada dessa função, deve-se utilizar a função rand() para gerar uma
sequencia de números aleactorios, cujo início é determinado pelo valor de s.

int system(const char *str); Executa um comando interno do sistema operativo


ou um programa com extensão EXE, COM ou BAT. Por exemplo, para limpar os
dados da tela, basta colocar no código do seu programa a chamada
system("CLS"); para congelar os dados do seu programa na tela, basta colocar
antes do témino do programa à chamada system("PAUSE");

Estrutura de Repetição 98

Você também pode gostar