Informática Numaboa - Tutoriais e Programação

Linguagem Perl - Loops e Saltos

Qui

20

Nov

2008


20:47

  • Imprimir
(1 voto de 5.00) 


Loops são alças, mas não adianta querer dourar a pílula. Ninguém vai saber do que eu estou falando se eu quiser chamar um loop de alça smile

Neste tutorial você vai aprender como se criam diversos tipos de loops. Também vai tomar contato com os saltos condicionais (curioso, ainda não encontrei ninguém que tenha trocado o termo salto por jump).

Loops com while e until

Com a ajuda dos loops while da linguagem Perl pode-se repetir diretivas do programa enquanto a condição da loop for verdadeira. Com um loop until pode-se repetir diretivas do programa até que a condição do loop seja atendida. Exemplo 1:

#!/usr/bin/perl $i = 1; print "primeiro a raiz quadrada de 1 até 10...\n\n"; while($i <= 10) { print "A raiz quadrada de ", $i, " é", sqrt($i), "\n"; $i++; } $i = 1; print "e agora os quadrados de 1 até 10...\n\n"; until($i > 10) { print "O quadrado de ", $i, " é", $i * $i, "\n"; $i++; }

Exemplo 2:

#!/usr/bin/perl $ArqAccesso = "../../docs/access.log"; $Acessos = 0; $Sucessos = 0; open(ARQUIVO, "<".$ArqAccesso) || die "Arquivo não encontrado!\n"; { while() { if(/HTTP\/1.0" 200/) # procurar por 'HTTP/1.0" 200' que são acessos bem sucedidos { $Sucessos++; } $Acessos++; } } print "De ", $Acessos, " acessos, ", $Sucessos, " foram bem sucedidos\n";

Um loop while (como o do exemplo 1) é iniciado com a palavra while (while = enquanto). Seguem-se as diretivas, contidas entre chaves. Para se formular uma condição é fundamental que as regras dos operadores de comparação sejam observadas. O conteúdo do loop é repetido enquanto a condição do loop for verdadeira.

Um loop until (como na segunda parte do exemplo 1) inicia-se com a palavra until (until = até que). Trata-se de uma formulação lógica diferente da do loop while. O conteúdo do loop until é repetido até que a condição do loop seja verdadeira. Nos demais aspectos, as regras do loop until são as mesmas que as do loop while. Entretanto, observe cuidadosamente a formulação da condição lógica! No exemplo, a condição while($i <= 10) acaba tendo exatamente o mesmo efeito que until($i > 10).

O exemplo 2 mostra um caso de aplicação típico do loop while em Perl. Neste exemplo, um arquivo é lido linha por linha. Trata-se de um arquivo de log, do tipo que os servidores web produzem para controlar os acessos. Neste caso específico, não há a necessidade de se usar um operador relacional (de comparação) na formulação da condição do loop. O loop é automaticamente interrompido quando todas as linhas do arquivo tiverem sido lidas (complemente esse exemplo verificando o módulo Leitura e Escrita de Arquivos, como também as expressões regulares na pesquisa em cadeias de caracteres).

As diretivas no interior de um loop sempre devem estar contidas entre chaves, mesmo quando houver apenas uma única diretiva.

info Observação: Em loops com operadores condicionais na condição do loop, deve-se sempre garantir pelo menos uma possibilidade de saída após o processamento apropriado. Isto significa que todas as condições devem ser verificadas cuidadosamente e que, com certeza, exista pelo menos uma saída válida, seja qual for o caso. Loops em que determinada condição não tenha uma saída prevista podem entrar no chamado "loop infinito" e o programa ou o sistema "travam".

Para se evitar um "loop infinito" é necessário que exista algo que, a um momento qualquer, leve à saída da alça. Para esse fim, frequentemente são definidos os chamados "contadores" - como no exemplo 1 a escalar $i. Esta escalar recebe um valor inicial de 1, que é incrementado em 1 a cada passagem através da diretiva $i++;. Desta forma, quando atingir um determinado valor e atender a condição do loop, este é interrompido.

Uma outra possibilidade de controlar e interromper loops é oferecida pelos saltos condicionais.

Loops com do..while/until

Neste tipo de loop, ao invés de primeiramente avaliar a condição da alça para depois executar o código dependente da condição, primeiro o bloco de diretivas é executado para depois a condição ser avaliada. Este tipo de loop, em todos os casos e independentemente do tipo de condição, é executado pelo menos uma vez. O uso deste tipo de loop é interessante quando as variáveis utilizadas na condição dependem de um processamento anterior. Exemplo 1:

#!/usr/bin/perl $Nome = "João"; do { print $Nome, "\n"; $Nome = "Pedro"; } while($Nome ne "Pedro")

Exemplo 2:

#!/usr/bin/perl $Nome = "João"; do { print $Nome, "\n"; $Nome = "Pedro"; } until($Nome eq "Pedro")

Um loop deste tipo começa com a palavra chave do. O bloco de diretivas vem logo a seguir, como sempre, entre chaves { }. Após a chave de fechamento }, encontra-se a condição de execução da alça. A condição pode ser formulada com while (enquanto) ou com until (até que). As regras restantes são as mesmas das alças com while/until.

info Observação: Os loops com do..while/until também sempre precisam ter uma opção de saída para não entrarem num "loop infinito". Os dois exemplos acima apresentam o mesmo resultado, ou seja, mostram o nome "João". Os exemplos diferem apenas na formulação da condição de execução da alça. Se os operadores relacionais eq (igual) e ne (não igual) fossem trocados, os dois loops entrariam num "loop infinito".


Loops com for/foreach

Os loops com for ou foreach diferenciam-se dos loops com while ou until por conterem uma condição fixa de término. Estas alças são adequadas nos casos em que o "valor inicial" e o "valor final" são previamente determinados. Exemplo 1:

#!/usr/bin/perl for($i=0;$i<=255;$i++) { printf("%4d = %2X",$i, $i); if($i % 8 == 0) { print "\n"; } }

Exemplo 2:

#!/usr/bin/perl @Alfabeto = (A..Z); for(@Alfabeto) { print $_, " é a ", $i+1, ". letra do alfabeto\n"; $i++; }

Exemplo 3:

#!/usr/bin/perl foreach $i (1..100) { next if $i % 2 == 0; print $i, "\n" if $i % 3 == 0; }

Um loop-for começa com a palavra chave for. A seguir, entre parênteses, é formulada a condição de execução da alça. Nos loops-for clássicos, de acordo com a linguagem C, no corpo das alças são anotadas três diretivas. Na primeira, um contador é definido e inicializado. No exemplo 1, o contador $i é definido e inicializado com o valor 0. A segunda diretiva contém a condição de finalização da alça. Para formular a condição, os operadores relacionais fazem-se necessários. Na terceira diretiva, o contador do loop é modificado de forma que, em algum momento, ele preencha a condição exigida pela segunda diretiva. No exemplo, $i é incrementado em 1 a cada passagem, de modo que o valor, em algum momento, será maior do que 255 e atenderá à condição de finalização. O exemplo 1 utiliza o contador para, a cada passagem, apresentar em notação hexadecimal o valor atual de $i. A condição if($i % 8 == 0) é o módulo da divisão que, quando for zero, força uma quebra de linha. A apresentação dos valores é obtida com a ajuda da função printf (a mesma da linguagem C) que permite uma saída limpa de dados formatados. Esta função, aliás, não é muito adequada para a CGI, ou seja, para saídas em forma de HTML.

O exemplo 2 mostra um caso especial, típico da Perl, da utilização de um loop-for. Esta forma é muito prática para processar sequencialmente os elementos de um array ou lista hash. No exemplo 2 foi criada uma lista @Alfabeto contendo todas as letras maiúsculas do alfabeto. Com a diretiva for(@Alfabeto) é colocada uma alça sobre esta matriz. A alça será automaticamente repetida tantas vezes quantos forem os elementos da matriz. Para obter o elemento atual da lista, é utilizada a variável predefinida $_, a qual guarda o conteúdo da mesma.

Uma outra construção típica em Perl é uma alça com foreach. O exemplo 3 mostra um destes loops em ação. Neste tipo de loop define-se como condição entre parênteses uma área única, por exemplo números (do Número..até Número) ou letras (da Letra..até Letra). A alça é automaticamente repetida até que todos os elementos da área definida tenham sido processados.

Se quisermos inserir um contador no interior do loop, pode-se definir uma variável contadora entre o foreach e a condição de execução da alça, assim como no exemplo 3 a escalar $i.

O exemplo 3 dá todos os números, entre 1 e 100, que sejam ímpares e divisíveis por 3. O camando de salto next auxilia o processamento.

Comandos de Salto em Perl

A linguagem Perl tem a fama de que, com ela, não é possível fazer uma programação bem estruturada. Apesar da Perl oferecer atualmente todas as possibilidades para uma programação de estrutura limpa e até para a programação orientada a objeto (OOP), ela é e continuará sendo uma linguagem para scripts onde os programadores frequentemente não se dão ao trabalho de distribuir o fluxo do programa em subrotinas específicas. Uma alternativa utilizada frequentemente numa programação estruturada são os comandos de salto para um outro ponto desejado no programa. Também no interior de loops, os comandos de salto são muito apreciados para, por exemplo, forçar uma passagem prematura pelo loop ou para interrompê-lo. Exemplo 1:

#!/usr/bin/perl # Adivinhe qual o valor de $i no final do processamento $i = 1; goto Resultado; while($i < 1000) { ++$i; if($i % 3 == 0) { redo; } elsif($i % 7 == 0) { next; } elsif($i % 13 == 0) { last; } elsif($i % 17 == 0) { continue; } } Resultado: print "Resultado: ", $i;

Exemplo 2:

#!/usr/bin/perl while($i < 10) { ++$i; if($i % 2 != 0) { redo; } } continue { print $i, "\n"; }

Os seguintes comandos de salto estão à disposição em Perl:

goto (go to = vá para) salta para uma outra parte desejada do programa. Para tanto, a referida parte precisa ser identificada por uma "Label" (label = etiqueta) que pode ser comparada à âncora do HTML. Uma label é definida por um nome seguido de dois pontos. No exemplo acima, na penúltima linha, foi definida a label Resultado:. O comando goto, no início do exemplo, força um salto para esta label. É o chamado salto incondicional.

redo (redo = refazer) foi projetado para ser utilizado no interior de laços. A passagem atual pelo laço é interrompida. A próxima passagem é iniciada sem que a condição de execução do loop seja avaliada. Se, por exemplo, o loop tiver um contador que é incrementado, o redo refaz a passagem pelo loop sem alterar o valor do contador.

next (next = próximo) também é para ser utilizado no interior de loops. A passagem atual é interrompida e a próxima passagem é iniciada após a avaliação da condição de execução do loop.

last (last = último) interrompe imediatamente um loop.

continue é um caso especial em Perl e deve ser tratado de forma diferente que em outras linguagens. O exemplo 2 mostra uma aplicação típica. continue inicializa um bloco de diretivas próprio, da mesma forma que o loops. No interior deste bloco que, como habitual, é demarcado pelas chaves { e }, podem ser anotadas as diretivas desejadas. Se um bloco continue estiver logo após um bloco de loop, ele também é repassado a cada passagem pelo loop. Com um comando de salto como redo no interior do bloco da alça, é possível evitar que o bloco continue sendo processado. No exemplo 2, esta construção tem como objetivo que todos os números pares entre 1 e 10 sejam mostrados.

Вадим Логофет отецкосметика White Line интернет магазинлобановский обыскквадрокоптер ценалобановский александр2dayалександр лобановский