Mostrando postagens com marcador laço. Mostrar todas as postagens
Mostrando postagens com marcador laço. Mostrar todas as postagens

sábado, 10 de abril de 2010

Conhecendo as Estruturas de Repetição

Na Ciência da Computação, uma estrutura de repetição é uma estrutura presente nas linguagens de programação, que possibilita repetir a execução de um bloco de comandos em um certo número de vezes, dependendo de uma condição verdadeira ou falsa. Também é conhecida como estrutura de laço.

Os componentes de uma estrutura de repetição são o comando de iteração, a condição de parada (expressão lógica ou expressão de controle) e o bloco de comandos, que geralmente possui delimitadores. Em algumas estruturas a condição é verificada antes do bloco de comandos. Neste caso pode ocorrer nenhuma execução do bloco. Em outras estruturas a condição é verificada após a primeira execução do bloco de comandos. Nesta o bloco é executado pelo menos uma vez.

Caso a condição de parada nunca aconteça, a repetição torna-se infinita, o que é um erro de programação. Em algumas linguagens de programação existem ainda palavras reservadas para sair da estrutura de repetição de dentro do bloco de comandos ("break" em C e "Exit Do" em Visual Basic, por exemplo) e para terminar a iteração atual do bloco de comandos e forçar uma nova verificação da condição ("continue" em C, por exemplo).

O comando "enquanto-faça"

Neste comando a verificação da condição é no início da estrutura, ou seja, antes de entrar no bloco de comandos a expressão lógica é verificada e caso o resultado for verdadeiro, os comandos que estão no bloco são executados. Após a execução dos comandos, a expressão lógica é novamente verificada. Caso o resultado da expressão lógica for falso, o algoritmo sai da estrutura de repetição e segue para a próxima linha.

Geralmente o comando que altera o valor utilizado na condição está inserido dentro do bloco de comandos ou depende de alguma variável externa que será fornecida em tempo de execução. O comando "enquanto-faça" é usado principalmente quando não se sabe com antecedência a quantidade de repetições que precisam ser realizadas.

Sua sintaxe básica em linguagem de algoritmo é:

enquanto <condição> faça
    <bloco de comandos>
fim enquanto

Exemplos em algumas linguagens de programação:

a) C

while(x<=10) {
    <comandos>;
}

b) Pascal

while x<=10 do
begin
    <comandos>;
end;

c) Visual Basic

Do While x<=10
    <comandos>
Loop

O comando "até-faça"

Neste comando a verificação da condição também é no início, ou seja, antes de entrar no bloco de comandos. Entretanto, os comandos que estão no bloco são executados caso o resultado da condição for falso. Após a execução dos comandos, a expressão lógica é novamente verificada. Caso o resultado da expressão lógica for verdadeiro, o algoritmo sai da estrutura de repetição e segue para a próxima linha.

E igualmente ao comando "enquanto-faça", o comando que altera o valor utilizado na condição está inserido dentro do bloco de comandos ou depende de alguma variável externa. O comando "até-faça" também é usado quando não se sabe com antecedência a quantidade de repetições que precisam ser realizadas.

Sua sintaxe básica em linguagem de algoritmo é:

até <condição> faça
    <bloco de comandos>
fim até

Exemplos em algumas linguagens de programação:

a) Visual Basic

Do Until i>10
    <comandos>
Loop

O comando "faça-enquanto"

Neste comando a verificação da condição é no final da estrutura, ou seja, a estrutura "faça-enquanto" difere da estrutura "enquanto-faça" somente por executar o bloco de comandos antes de verificar se a condição é verdadeira. Assim, utilizando o "faça-enquanto" o bloco de comandos é sempre executado pelo menos uma vez, mesmo que a condição seja falsa.

Se a condição for verdadeira o bloco é executado, também o comando de alteração do valor para a condição deve estar dentro do bloco de comandos ou vindo de uma variável externa, e também é usado quando não se sabe com antecedência a quantidade de repetições que precisam ser realizadas.

Sua sintaxe básica em linguagem de algoritmo é:

faça
    <bloco de comandos>
enquanto <condição>

Exemplos em algumas linguagens de programação:

a) C

do {
    <comandos>;
} while(x<=10);

b) Visual Basic

Do
    <comandos>
Loop While i<=10

O comando "faça-até"

Neste comando a verificação da condição é no final da estrutura, ou seja, a estrutura "faça-até" difere da estrutura "até-faça" somente por executar o bloco de comandos antes de verificar se a condição é falsa. Assim, utilizando o "faça-até" o bloco de comandos é sempre executado pelo menos uma vez, mesmo que a condição seja verdadeira.

Se a condição for falsa o bloco é executado, também o comando de alteração do valor para a condição deve estar dentro do bloco de comandos ou vindo de uma variável externa, e também é usado quando não se sabe com antecedência a quantidade de repetições que precisam ser realizadas.

Sua sintaxe básica em linguagem de algoritmo é:

faça
    <bloco de comandos>
até <condição>

Exemplos em algumas linguagens de programação:

a) Pascal

repeat
    <comandos>;
until i>10;

b) Visual Basic

Do
    <comandos>
Loop Until i>10

O comando "para-faça"

A estrutura "para-faça" é composta de um mecanismo de controle que estabelece de antemão quantas vezes a iteração será executada. A estrutura para ser utilizada precisa das informações referentes aos valores de início, fim e incremento do passo. Nesta estrutura, uma determinada variável assumirá valores pertencentes ao intervalo identificado pelos valores de início e fim, respeitando o incremento informado, cujo comando é realizado dentro da própria expressão de controle.

Neste comando a verificação da condição é no início da estrutura e a execução do bloco de comandos é repetida em um número pré-determinado, teoricamente fixo. Quando o valor do fim for alcançado, o algoritmo sai da estrutura de repetição e segue para a próxima linha.

Sua sintaxe básica em linguagem de algoritmo é:

para variável de início até fim passo incremento faça
    <bloco de comandos>
fim parada

Exemplos em algumas linguagens de programação:

a) C

for(i=1; i<=10; i++) {
    <comandos>;
}

b) Pascal

for i:=1 to 10 do
begin
   <comandos>;
end;

c) Visual Basic

For i=1 To 10 Step 1
   <comandos>
Next

Os comandos de iteração não estão todos presentes em todas as linguagens, como percebido pelos exemplos apresentados neste artigo. Um comando ausente em determinada linguagem entretanto pode ser substituído por outro existente, com algumas adaptações na lógica do algoritmo. Este artigo limitou-se em apenas apresentar exemplos nas linguagens C, Pascal e Visual Basic.

domingo, 17 de janeiro de 2010

Automatize sequências de comandos no prompt do shell com laços

Um comando de iteração, ou laço, permite que um conjunto de instruções seja executado repetidamente até que ocorra uma certa condição. No Linux o interpretador de comandos Bash, da mesma forma que às principais linguagens de programação, também possui os comandos básicos de iteração e são os comandos for, while e until.

O comando for é o mais simples dos três, utiliza um contador com um início e fim pré-definido e o incremento do passo. Durante cada passo a variável "argumento" recebe o valor de cada membro da "lista". O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:

for argumento in lista
do
comando(s)
done


Como vamos executar todo o comando em uma única linha no prompt do shell, então é necessário alguns ponto-e-vírgulas:

for argumento in lista; do comando(s); done


Veja alguns exemplos de lista para compor um contador para a repetição. Nos casos abaixo todos produzem o mesmo efeito, contando de 1 à 10. Em dois exemplos foi usado o utilitário seq, que imprime uma sequência de números:

for i in 1 2 3 4 5 6 7 8 9 10; do echo -n "$i "; done
for i in $(seq 10); do echo -n "$i "; done
for i in `seq 10`; do echo -n "$i "; done
for i in {1..10}; do echo -n "$i "; done
for ((i=1; i<=10; i++)); do echo -n "$i "; done


A lista de valores pode conter palavras ao invés de números, veja estes exemplos. O segundo exemplo utiliza um arquivo que contém as palavras:

for dia in Segunda Terça Quarta Quinta Sexta; do echo $dia; done
for dia in `cat semana.txt`; do echo $dia; done


O incremento do passo pode ser mais de 1 em 1. Os exemplos abaixo produzem o mesmo efeito, contando de 1 à 16 com passo 2:

for ((i=1;i<=16;i+=2)); do echo $i; done
for i in $(seq 1 2 16); do echo $i; done
for i in `seq 1 2 16`; do echo $i; done
for i in 1 3 5 7 9 11 13 15; do echo $i; done
foi i in {1..16..2}; do echo $i; done # A partir do bash versão 4.


É possível também utilizar duas variáveis no contador, na sintaxe semelhante à linguagem C:

for ((i=1, j=1; i<=10; i++, j++)); do echo -n "$i-$j "; done


Exemplos práticos com o uso do comando for:

for i in *.*; do novo="$(echo "$i" | sed 'y/ÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÇÑàáâãäåèéêëìíîïòóôõöùúûüçñ/
AAAAAAEEEEIIIIOOOOOUUUUCNaaaaaaeeeeiiiiooooouuuucn/')"; mv "$i" "$novo"; done

for i in `ls *-6_*.pdf`; do mv $i ${i/-6_/-06_}; done

n=1; for nome in $(awk 'BEGIN{FS=":"}{print $1}' < /etc/passwd ); do echo "USUARIO #$n = $nome";
let n+=1; done

for file in *.mp3; do mkdir -p "$(mp3info -p "%a/%l" "$file")" && mv "$file" "$(mp3info -p
"%a/%l/%t.mp3" "$file")"; done

for x in $(lynx -dump http://marx.vanderlinden.com.br/sem/2009.1/fi.php | awk '{print $2}' | grep
.pdf); do wget -c $x; done

for arquivo in $( find /usr/local/bin/ -type f -name '*' | sort ); do strings -f $arquivo | grep
"GPL" | sed -e "s%/usr/local/bin/%%"; done


O comando while testa por uma condição no início do laço e mantém a iteração enquanto esta condição é verdadeira (retorna 0 quando falso). Diferentemente do comando for, o comando while é usado quando o número de repetições não é conhecido de antemão. O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:

while condição
do
comando(s)
done


Mais uma vez, como vamos executar todo o comando em uma única linha, no prompt do shell, então é necessário alguns ponto-e-vírgulas:

while condição; do comando(s); done


Para o comando while executar o laço a condição já deve existir. Veja este exemplo onde é inicializada a variável de controle antes do comando while (Obs.: é necessário os espaços dentro dos colchetes pois é um teste de condição):

i=1; while [ $i -le 10 ]; do echo -n "$i "; let i+=1; done


Ou, produzindo o mesmo resultado:

i=1; while ((i<=10)); do echo $i; ((i+=1)); done


Uma outra forma, por exemplo, é suprir a entrada com o conteúdo de um arquivo:

cat semana.txt | while read linha; do echo -n "$linha "; done


Ou, produzindo o mesmo resultado:

while read linha; do echo -n "$linha "; done < <(cat semana.txt)


Exemplos práticos com o uso do comando while:

find /usr/share/ -regextype posix-egrep -iregex '.*\.(jpg|jpeg|gif|png|tif|tiff|bmp|svg)' -type f
-print | while read IMAGEM; do convert -thumbnail 120x120 -compress JPEG -quality 20 -delete 1--1
"$IMAGEM" thumbs/"$(echo "${IMAGEM}" | sed 's/.*\///g')".jpg; done

while read nome; do echo "USER #$n = $nome"; let n+=1; done < <(awk 'BEGIN{FS=":"}{print $1}'
< /etc/passwd )

seq 1 100 | while read i; do echo -n "texto${i}.txt "; touch texto${i}.txt 2>&1; done

while read i; do echo -n "texto${i}.txt "; touch texto${i}.txt 2>&1; done < <(seq 1 100)

while read arquivo; do strings -f $arquivo | grep "GPL" | sed -e "s%/usr/local/bin/%%";
done < <( find /usr/local/bin/ -type f -name '*' | sort )


O comando until testa por uma condição no início do laço e mantém esta iteração enquanto a condição for falsa (diferentemente do comando similar em outras linguagens), sendo o oposto do comando while. Também o comando until é usado quando o número de repetições não é conhecido de antemão. O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:

until condição
do
comando(s)
done


Como sempre, vamos executar todo o comando em uma única linha, no prompt do shell, então é necessário alguns ponto-e-vírgulas:

until condição; do comando(s); done


Também como o comando while, para o until executar o laço a condição já deve existir. Neste exemplo é inicializada a variável de controle antes do comando until:

i=1; until [ $i -gt 10 ]; do echo $i; let i+=1; done


Ou, produzindo o mesmo resultado:

i=1; until ((i>10)); do echo $i; ((i+=1)); done


Da mesma forma que demonstrado no comando while, também é possível suprir a entrada com o conteúdo de um arquivo.

Exemplos práticos com o uso do until:

until [ -e teste.txt ]; do echo -e "Crie o arquivo teste.txt\n"; sleep 5; done

until [ $(ls -l eventos.log | awk '{print $5}') -gt 5000 ]; do echo "Arquivo log ainda pequeno";
sleep 1; done


Nestes três comandos de iteração é possível interromper o comando ou somente pular o passo atual e continuar no próximo. Para isso usa-se respectivamente os comandos break e continue na posição desejada entre o do e o done. Obviamente para ter este controle certamente vai ser necessário o uso de um comando condicional, como o if.

Como escolher entre os laços for, while ou until? Pode ser possível conseguir o mesmo efeito com os três comandos de laço. Veja os comandos abaixo, todos produzem o mesmo resultado, então provavelmente o melhor será aquele que visualmente for mais fácil de entender o algoritmo. Mas observe que o comando for é mais utilizado quando o número de iterações é conhecido e os comandos while e until servem para um número impreciso de iterações:

for ((i=1; i<=10; i++)); do echo "$i "; done
i=1; while ((i<=10)); do echo $i; ((i+=1)); done
i=1; until ((i>10)); do echo $i; ((i+=1)); done