Estruturas de Repetição
Comando while do ... done
Programação de Scripts
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
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
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
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
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
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
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
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,
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.