Estruturas de Repetição Comando while do ... done
Programação de Scripts
Prof. Kleber Rezende
Considerações Iniciais
Quando não temos condições de
determinar, de forma precisa,
quantas vezes um determinado
conjunto de comandos precisa ser
executado, devemos utilizar outras
Estruturas de Repetição, como:
While do ... done ou
Until do ... done
Considerações Iniciais
Por exemplo, suponha que estamos
oferecendo ao usuário 3 opções de menu
sendo que uma dessas 3 opções seria a
opção de SAIR do programa.
Caso desejemos que o usuário possa
executar várias vezes as opções dispostas no
menu, não temos como adivinhar quando o
usuário irá optar por SAIR do algoritmo
Sendo assim, não podemos limitar a repetição
a um número de vezes.
Considerações Iniciais
Considere um problema mais específico onde
necessitamos fazer a leitura de vários nomes
de pessoas e a cada nome que é lido
devemos escrever na tela a frase "O nome
digitado foi NOME".
A princípio isso deve ser feito inúmeras vezes
e quando o usuário digitar um NOME igual a
FIM o algoritmo deve parar.
Considerações Iniciais
Da mesma maneira que no exemplo anterior,
não podemos definir quando o usuário irá
digitar FIM, e não temos como precisar a
quantidade de vezes que o algoritmo deverá
repetir esse conjunto de ações.
Considerações Iniciais
Nessas situações, a repetição de um conjunto
de comandos é determinada pela avaliação de
resultado de um comando, ou seja:
caso o comando seja executado com êxito o
conjunto de comandos internos continua a ser
executado,
caso o comando falhe a estrutura de repetição é
abortada.
Considerações Iniciais
A estrutura de repetição “while do ... done" é utilizada
da seguinte maneira:
while <COMANDO>
do
comando 1
comando 2
.
.
.
comando n
done
Considerações Iniciais
Por exemplo, para ler o conteúdo de um arquivo linha
por linha, podemos usar a seguinte estrutura:
while read linha
do
echo $linha
done < arquivo.txt
Considerações Iniciais
Assim como acontece na estrutura condicional
if, o comando while pode usar o par de
colchetes (que representa o comando test)
para avaliar expressões lógica com um
sintaxe semelhante àquele encontrada em
outras linguagens de programação.
while [ <EXP_LOGICA> ]
do
<LISTA_DE_COMANDOS>
done
Considerações Iniciais
Antes de entrar na estrutura de repetição, a
expressão lógica é avaliada;
Caso o resultado da mesma seja VERDADEIRO os
comandos que estão dentro da estrutura serão
executados e ao final volta-se a avaliar a
expressão lógica novamente.
Caso o resultado da expressão lógica seja falso, o
algoritmo sai da estrutura de repetição.
Exemplos
Considere o script abaixo:
nome=""
while [ $nome != "fim" ]
do
echo –n "Digite o nome: “
read nome
echo "O nome digitado foi $nome"
done
Estrutura de Repetição
Fluxograma
nome ← ""
Início
nome != "fim"?
Fim
Escreva "digite o nome: "
Verdadeiro
Falso
Leia nome
Escreva "o nome digitado foi " + nome
Transformando comando FOR em
comando WHILE
A estrutura de repetição WHILE deve ser
utilizada, especialmente, quando não
podemos determinar o número de vezes que
o conjunto de comandos será repetido;
Porém, nada impede que utilizemos uma
expressão lógica que avalie o valor de um
número, simulando dessa forma uma
estrutura de repetição FOR.
Transformando comando FOR em
comando WHILE
Suponha que desejemos realizar
um conjunto de operações 10
vezes, como por exemplo, pedir a
idade de 10 pessoas e calcular a
soma dessas 10 idades.
Transformando comando FOR em
comando WHILE Utilizando a estrutura de repetição FOR teríamos o
seguinte script:
soma=0
for ((cont=1; cont <= 10; cont++))
do
echo –n "Digite a idade: "
read idade
let soma=soma+idade
done
echo "A soma das idades = $soma"
Transformando comando FOR em
comando WHILE
Caso desejássemos escrever esse
mesmo algoritmo utilizando a estrutura
de repetição WHILE, teríamos que nos
preocupar em avaliar uma expressão
lógica que garanta que o contador
chegue ao número máximo de 10 vezes,
ou seja, o contador deve ser sempre
menor ou no máximo igual a 10.
Transformando comando FOR em
comando WHILE
Além disso, é importante ressaltar que
diferentemente da estrutura FOR, a
estrutura de repetição WHILE deve se
preocupar em incrementar o seu
contador, ou seja, a cada iteração
devemos fazer com que o contador
aumente o seu valor em um.
Transformando comando FOR em
comando WHILE Veja o algoritmo a seguir:
soma=0
cont=1
while [ $cont -le 10 ]
do
echo –n "Digite a idade: "
read idade
let soma=soma+idade
let cont=cont+1
done
echo "A soma das idades = $soma"
Transformando comando FOR em
comando WHILE
Mas afinal, qual seria a vantagem de
utilizarmos a estrutura WHILE para esse tipo
de situação, considerando que já possuímos a
estrutura de repetição FOR?
A vantagem está no fato da estrutura de repetição
WHILE nos permitir utilizar expressões lógicas
compostas, ou seja, podemos trabalhar com
contadores ao mesmo tempo em que avaliamos
outras variáveis do nosso algoritmo.
Exemplo
Suponhamos que necessitamos realizar um
algoritmo semelhante ao do exemplo anterior;
Porém agora além de limitarmos o número
máximo de pessoas em 10, queremos
também limitar a soma das idades dessas
pessoas.
Exemplo
Por exemplo, o algoritmo deve solicitar as
idades das pessoas, enquanto o número de
pessoas não chegar a 10, e também enquanto
a soma de idade dessas pessoas não
ultrapassar 100 anos.
Caso uma dessas condições não seja
obedecida a estrutura de repetição deverá ser
abortada.
Exemplo
Vejamos como ficaria esse algoritmo :
soma=0
cont=1
while [ $cont -le 10 ] && [ $soma –lt 100 ]
do
echo –n "Digite a idade: "
read idade
let soma=soma+idade
let cont=cont+1
done
echo "Número de pessoas = $(($cont-1))"
echo "A soma das idades = $soma"
Exercício Comentado
Sabemos que um determinado elevador tem
espaço para no máximo 7 pessoas e pode
suportar transportar até 500 kg. Como você
desenvolveria um algoritmo para permitir a
entrada de pessoas nos elevadores
considerando essas condições e utilizando a
estrutura de repetição ENQUANTO?
Solução Possível
pesototal=0
cont=1
while [ $cont -le 7 ] && [ $pesototal –le 500 ]
do
echo –n "Peso do próximo a subir: "
read peso
let pesototal=pesototal+peso
let cont=cont+1
done
echo "Número de pessoas que subiram= $(($cont-1))"
echo "Peso total no elevador = $pesototal"
Problema!!!!!
A solução anterior apresenta um problema.
Você consegue identificar qual seria esse
problema?
O problema existente é que mesmo depois de realizar
a verificação do pesototal, é possível que a soma do
pesototal com o próximo peso exceda 500 quilos. Isso
acontece pois dentro da estrutura de repetição o
pesototal é somado com o valor do peso que foi
recentemente lido, e o resultado dessa soma somente
é verificado para a realização da próxima iteração.
Teste de Mesa
Por exemplo, considere a execução do algoritmo para
os seguintes valores:
cont Peso Pesototal Pesototal <= 500
1 100 100 VERDADEIRO
2 100 200 VERDADEIRO
3 120 320 VERDADEIRO
4 120 440 VERDADEIRO
5 120 560 FALSO
Problema!!!!!
Ao chegar na 4a iteração, quando o contador
cont está com o valor 4, o peso lido será de
120 quilos e o pesototal será de 440.
Ao sair dessa iteração, o algoritmo irá avaliar
se o pesototal é menor ou igual a 500, e o
resultado será verdadeiro.
Entrando novamente na estrutura de repetição
e indo para a 5a iteração, o peso lido será de
120 quilos e o pesototal irá para 560 quilos,
excedendo o limite do elevador.
Solução Alternativa
Uma alternativa seria fazer a avaliação
antecipada da soma do pesototal e do peso
da próxima pessoa que iria entrar no elevador.
Solução Alternativa
cont=1
echo –n "Peso do próximo a subir: "
read pesototal
while [ $cont -le 7 ] && [ $pesototal –le 500 ]
do
echo –n "Peso do próximo a subir: "
read peso
let pesototal=pesototal+peso
let cont=cont+1
done
echo "Número de pessoas que subiram= $(($cont-1))"
echo "Peso total no elevador = $(($pesototal-$peso))"
Exercícios
1. Elabore um script que entre com números enquanto forem
positivos e imprimir quantos números que foram digitados
(incluindo o último número).
2. Elabore um script que entre com números enquanto forem
positivos e imprima ao final a soma dos números que foram
digitados).
3. Elabore um script que entre com vários números positivos e
imprima ao final a média dos números digitados.
4. Elabore um script que solicite ao usuário quantidade de
números que ele irá digitar, leia esses vários números e
imprima o maior, o menor e a média aritmética dos números.
Exercícios
5. Construir um script que solicite ao usuário o número de
pessoas de uma determinada família, a idade em anos de cada
uma das pessoas, e que calcule a média de idade da família
(correspondendo a soma de todas as idades divididas pelo
número de pessoas).
6. Elabore um script que leia a idade e sexo (0 – masculino, 1 –
feminino) de várias pessoas (solicite ao usuário o número de
pessoas). Calcule e imprima a idade média, total de pessoas do
sexo feminino com idade entre 30 e 45 anos inclusive, e o
número total de pessoas do sexo masculino. O script termina
quando se digita 0 para a idade.
Exercícios
7. Elabore um script que leia a idade e o estado civil (c – casado,
s – solteiro, v – viúvo, e d – desquitado ou separado) de várias
pessoas. Considere que o script termina quando se digita um
número menor do que 0 para a idade. Ao final, calcule e
imprima:
a) A quantidade de pessoas casadas;
b) A quantidade de pessoas solteiras;
c) A média das idades das pessoas viúvas;
d) A porcentagem de pessoas desquitadas ou separadas,
dentre todas as pessoas analisadas.
Exercícios
8. Escreva um conjunto de scripts para gerenciar o apagamento
de arquivos. O script del deve mover os arquivos passados
como parâmetros para um diretório lixeira; o script undel deve
mover arquivos da lixeira para o diretório corrente e o
script lsdel deve listar o conteúdo da lixeira. O diretório
lixeira deve ser definido através da variável de
ambiente $LIXEIRA.
9. Funda os scripts do exercício anterior em um só script del, com
os demais (undel e lsdel) sendo links simbólicos para o
primeiro. Como fazer para que o script saiba qual a operação
desejada quando ele for chamado, sem precisar informá-lo via
parâmetros?
Exercícios
10. Escreva um script para verificar quais hosts de uma
determinada rede IP estão ativos. Para testar se um host está
ativo, use o comando ping. A rede deve ser informada via linha
de comando, no formato x.y.z, e o resultado deve ser enviado
para um arquivo com o nome x.y.z.log. Deve ser testada a
acessibilidade dos hosts de x.y.z.1 a x.y.z.254.