Aprender PHP

Assine o RSS

O loop for, as estruturas de controle aninhadas, o break e o continue no PHP

Criado em: 16/08/2010

Introdução

No artigo anterior aprendemos como utilizar os laços de repetição while e do while no PHP para realizarmos rotinas que deviam ser executadas um certo numero de vezes. Porém existe uma possibilidade de facilitar o uso de contadores finitos, sem utilizarmos o uso do while e do do while. E está possibilidade é o que veremos agora com a estrutura de controle for.

Problema

Vamos continuar com o mesmo problema do artigo anterior sobre while e do while para quem não se lembra do problema: Bart Simpson ficou novamente na detenção no final da aula. E como punição terá que escrever: “Estou aprendendo loopings no Aprender PHP” 100 vezes no quadro, ou no nosso caso na tela.

Sabemos que com o while e o do while podemos resolver este problema facilmente, no entanto agora vamos ver uma abordagem diferente com o uso do looping for.

O looping for no PHP

Assim como o while e o do-while o for é uma estrutura de controle responsável pela realização de loopings no PHP.

O comando for aceita 3 expressões na sua declaração sendo elas:

  1. Expressão que é avaliada apenas uma vez na primeira iteração, volta, do looping. Geralmente a utilizamos para iniciar a nossa variável de controle, contador, como por exemplo $i = 1.
  2. Expressão que é avaliada no inicio de cada iteração do looping, e caso retorne falso, o looping for será encerrado. A segunda expressão como você pode ver pode ser considerada a condicional do nosso looping, assim como tínhamos no while e no do while. Um exemplo seria $i <= 100.
  3. Expressão que é avaliada no final de cada iteração do looping, normalmente utilizada para alterar o valor da variável de controle. Como por exemplo utilizar o operador de incremento $i++.

Diagrama de bloco

Observe como seria a representação do problema de Bart Simpson utilizando o for.

Looping for no php representação em diagrama de blocos

Iniciamos com o bloco de processamento de dados que já é conhecido nosso para criarmos a mensagem que vai ser exibida e atribuímos o valor a variável $mensagem. Em seguida para representarmos o loop utilizamos o símbolo denominado Processamento predefinido ou Preparação com os valores da expressão do for o inicio, meio e fim, que foram apresentados a você no tópico anterior. Também utilizamos as setas para indicar o processamento e as letras S e N em que S representa o caminho a ser seguido caso a condição seja verdadeira e N caso a condição seja falsa.

No PHP

Agora vejamos como seria a representação em PHP da nossa estrutura de controle for para resolvermos o problema de Bart Simpson.

<?php
$mensagem = 'Estou aprendendo loopings no Aprender PHP';

for( $i = 1; $i <= 100; $i++ ){

  echo $i . ' - ' .$mensagem . '<br />' . PHP_EOL ;

}

?>

Como você pode observar diferentemente do while e do do-while não necessitamos incrementar o contador dentro do nosso looping pois isto já fica implícito na própria declaração do for. E detalhe que o separador de instruções, expressões, no for é o ;(ponto e virgula).

Em relação à estrutura de controle for:

  • Declara-se 3 expressões no inicio do for
    • Sendo a 1ª expressão avaliada apenas uma vez. Normalmente utilizada para criação da variável de controle.
    • 2ª expressão é avaliada no inicio de cada iteração, caso esta expressão retorne falso o looping é encerrado. Podendo ser considerada a condicional do for.
    • 3ª Expressão é avaliada no final de cada iteração, normalmente utilizada para alterar o valor da variável de controle.
  • Separa-se as expressões utilizando o ;(ponto e virgula).
  • O looping é executado enquanto a condição da 2ª expressão for verdadeira (True)
  • Quando a condição da 2ª expressão for avaliada como falsa (False) o processamento da rotina é desviado para fora do looping
  • O bloco de código referente ao looping deve ser delimitado por chaves {}
  • Endente o código referente ao bloco em 4 espaços por questões de legibilidade, a como configurar o seu editor de texto para transformar Tabs em espaços
  • Utilizamos um contador para o looping não ficar um looping infinito, este declarado na 1ª expressão
  • Não se esqueça de alterar o valor do contador, na 3ª expressão, para não cairmos em um looping infinito.

Estruturas de controle aninhadas

Antes de continuarmos com as estruturas de controle break e continue devemos saber um conceito importante as estruturas de controle aninhadas.

Também conhecido como desvio condicional encadeado, as estruturas de controle aninhadas são utilizadas em casos em que é necessário estabelecer verificações de condições sucessivas, ou seja, condições dentro de condições. Este tipo de estrutura pode possuir diversos níveis de condições aninhadas. Vamos a um exemplo.

Problema

Como acabamos de aprender o looping for utilizaremos ele neste exemplo. Nosso problema é o seguinte:

  • criar um programa que escreve de 1 a 100
  • imprimir todos os números
  • ao lado de todos os número mostrar se o número é par ou impar

Diagrama de bloco

Observe como seria no diagrama de blocos a resolução do nosso problema.

Diagrama de blocos de estruturas aninhadas no php

Como você deve ter observado não possuímos nenhum símbolo novo no nosso diagrama de blocos. Iniciamos a resolução do nosso problema com o símbolo denominado Processamento predefinido ou Preparação para representarmos o looping for, onde inserimos a sua lógica. Caso o for retorne falso o processamento é encerrado e nada é exibido. Caso retorne verdadeiro iniciamos o looping e nos deparamos com uma estrutura aninha que é representada por um símbolo de decisão, o losango. No símbolo de decisão a lógica é avaliada, caso o valor retornado seja verdadeiro exibe o número e diz que é par, caso retorne falso o número é exibido e diz-se que é impar. Após exibirmos o valor utilizamos o pequeno circulo, o conector, que foi utilizado para conectar as condições e todas levarem para um mesmo destino, o inicio do looping for.

No PHP

Agora vamos ver no PHP como ficaria no PHP a representação do diagrama de blocos anterior.

<?php

for( $i = 1; $i <= 100; $i++ ){

  if ( $i % 2 == 0 ){
    echo $i . ' é par ' . '<br />' . PHP_EOL;
  } else {
    echo $i . ' é impar ' . '<br />' . PHP_EOL;
  }

}

?>

Inicialmente o mesmo looping for que aprendemos, no entanto observe que dentro do looping surgiu uma condicional if que é a nossa estrutura de controle aninhada, pois se encontra dentro do looping for.

A nossa lógica do if é: se $i módulo de 2 for igual a zero retorna verdadeiro caso contrário falso. Ou seja se dividir $i por 2 e não houver resto significa que $i é par se não é impar.

Caso esteja em dúvida com a estrutura de controle if ou o com o operador de módulo acesse seus respectivos artigos.

No PHP aninhando um pouco mais

Agora que já temos o conceito de estruturas de controle aninhadas mostrarei mais um exemplo prático no PHP, com mais de um nível de aninhamento.

Mostrarei direto no PHP, no entanto ele também pode ser representado no diagrama de blocos, não o representarei no diagrama de blocos, pois o conceito no diagrama de blocos foi explicado no exemplo anterior.

Problema
  • Definir um número premiado entre 1 e 100
  • criar um programa que escreve de 1 a 100
  • imprimir todos os números
  • Se o número for o premiado mostrar ele com um destaque e escrever que é o premiado
  • ao lado de todos os número mostar se o número é par ou impar, exceto do número premiado

Veja como poderíamos resolver este problema no PHP:

<?php

$premiado = 77;

for( $i = 1; $i <= 100; $i++ ){

  if( $i == $premiado ){

    echo '<strong>' .  $i . ' é o número premiado ' . '</strong><br />' . PHP_EOL;

  } else {

      if ( $i % 2 == 0 ){
        echo $i . ' é par ' . '<br />' . PHP_EOL;
      } else {
        echo $i . ' é impar ' . '<br />' . PHP_EOL;
      }

  }

}

?>

Como você deve ter observado o programa é bem parecido com o anterior a diferença é que agora criei uma variável com o nome de $premiado que armazenará o número premiado.
E dentro do looping for antes de verificar se é par ou impar, verifico primeiro se o número é o premiado, se for o exibo e escrevo que ele é premiado dentro de uma tag strong se não faço a mesma verificação anterior para ver se ele é par ou impar. Sendo assim a verificação de par ou impar foi aninhada por uma verificação para ver se é o número premiado ou não.

Se observar bem temos uma falha. Nada nos diz que o número premiado deve estar entre 1 e 100 sendo assim se a pessoa colocar um número maior que 100 não teremos nenhum premiado veja só um exemplo.

<?php

$premiado = 700;

for( $i = 1; $i <= 100; $i++ ){

  if( $i == $premiado ){

    echo '<strong>' .  $i . ' é o número premiado ' . '</strong><br />' . PHP_EOL;

  } else {

      if ( $i % 2 == 0 ){
        echo $i . ' é par ' . '<br />' . PHP_EOL;
      } else {
        echo $i . ' é impar ' . '<br />' . PHP_EOL;
      }

  }

}

?>

Mais em nosso jogo por política da casa sempre teremos um vencedor. Sendo assim temos que limitar a escolha dos números entre 1 e 100. Abaixo como limitar a escolha entre 1 e 100 mais antes de olhar o código pare um pouco aqui e tente resolver por si só.

<?php

$premiado = 77;

if( $premiado < 100 ){

    for( $i = 1; $i <= 100; $i++ ){

      if( $i == $premiado ){

        echo '<strong>' .  $i . ' é o número premiado ' . '</strong><br />' . PHP_EOL;

      } else {

          if ( $i % 2 == 0 ){
            echo $i . ' é par ' . '<br />' . PHP_EOL;
          } else {
            echo $i . ' é impar ' . '<br />' . PHP_EOL;
          }

      }

    }

} else {

  echo 'O número deve ser menor que 100';

}

?>

Como você deve ter imaginado apenas aninhamos toda a nossa estrutura anterior em uma condicional, ou seja, antes de iniciar o looping para dizer qual o premiado, primeiro verificamos se o $premiado que foi passado é menor que 100 se for iniciamos o mesmo processo anterior se não retornamos uma mensagem dizendo que o número deve ser menor que 100.

Em relação as estruturas de controle aninhadas:

  • Podem ser aninhadas as estruturas de controle como também os laços de repetições, loopings
  • Não a limite de condições que podemos aninhar
  • No entanto o bom senso conta, não crie um aninhamento de por exemplo 10 níveis será difícil de entender quando for ver o código novamente
  • Se as estruturas aninhadas estiverem com uma grande quantidade de níveis tente rever sua lógica
  • Endente o código referente ao bloco em 4 espaços por questões de legibilidade, a como configurar o seu editor de texto para transformar Tabs em espaços
  • Cada estrutura aninhada também deve ser endentada em 4 espaços onde a sua estrutura pai terminou, veja nos exemplos anteriores

Break

A instrução break é utilizada para encerrar a execução dos comandos for, foreach, falaremos deste posteriormente, while, do-while e switch. Permitindo que encerremos a instrução a qualquer momento que desejarmos, sendo assim podemos avaliar uma expressão e de acordo com o seu resultado encerrar a instrução.

Problema

  • Utilizar o código criado anteriormente, no entanto agora ao chegar ao número premiado o looping é encerrado.

No PHP

Para resolvermos o problema com o conhecimento que possuímos até aqui sem o uso do break poderíamos simplesmente fazer do seguinte modo:

<?php

$premiado = 77;

if( $premiado < 100 ){

    for( $i = 1; $i <= 100; $i++ ){

      if( $i == $premiado ){

        echo '<strong>' .  $i . ' é o número premiado ' . '</strong><br />' . PHP_EOL;
        $i = 100;

      } else {

          if ( $i % 2 == 0 ){
            echo $i . ' é par ' . '<br />' . PHP_EOL;
          } else {
            echo $i . ' é impar ' . '<br />' . PHP_EOL;
          }

      }

    }

} else {

  echo 'O número deve ser menor que 100';

}

?>

Simplesmente fizemos a condição do looping retornar falso, para isso definimos $i com o valor de 100 pois a condição do looping dizia que ele operaria até $i for menor ou igual a 100.

Caso esteja em dúvida com o looping for volte um pouco e recapitule o que cada uma de suas expressões representam.

Agora veja um exemplo de como podemos usar o break para resolver o mesmo problema.

<?php

$premiado = 77;

if( $premiado < 100 ){

    for( $i = 1; $i <= 100; $i++ ){

      if( $i == $premiado ){

        echo '<strong>' .  $i . ' é o número premiado ' . '</strong><br />' . PHP_EOL;
        break;

      } else {

          if ( $i % 2 == 0 ){
            echo $i . ' é par ' . '<br />' . PHP_EOL;
          } else {
            echo $i . ' é impar ' . '<br />' . PHP_EOL;
          }

      }

    }

} else {

  echo 'O número deve ser menor que 100';

}

?>

Simplesmente substituímos à atribuição de um valor a $i para tornar a condição do looping falsa por uma instrução break. Sendo assim ao utilizar o break automaticamente o looping é encerrado e o processamento continua fora do looping.

Break e o seu valor opcional

O break pode receber um valor opcional indicando quantos níveis devem ser encerrados, caso possua estruturas de controle aninhadas.

Problema

  • Programa que escreva de 1 a 100
  • E abaixo de cada número exiba a frase “Contando...” e os 5 próximos números
  • E quando o número da contagem for igual a 7 parar todo o processamento

No PHP

Veja como poderíamos resolver este problema

<?php

for( $i = 1; $i <= 100; $i++ ){

  echo '<br />' . $i . '<br />' . PHP_EOL;
  echo 'Contando...';

  for( $j = $i + 1; $j <= $i + 5; $j++ ){

    if( $j != $i + 5 ){
      echo $j . ', ';
    } else {
      echo $j;
    }

    if($j == 7){
      break 2;
    }

  }

}


?>

Primeiro criamos um for para mostra os números de 1 a 100 e a frase “Contando...”, dentro deste looping criamos outro looping for, observe que neste utilizamos como contador $j que possui o valor de $i + 1 e como é para mostrar os 5 números próximos a partir do número antes do contando utilizamos o valor $i + 5 e incrementamos $j. Utilizamos $i para atribuir os valores a $j devido a $i ser trocado em toda volta sendo assim sempre teremos $j dinâmico de acordo com o valor de $i. Dentro do looping possuímos um if que verifica se não é a ultima volta do looping se não for coloca virgula quando for a ultima não coloca a virgula. E o outro if é quando verificamos se $j é igual a 7 se for utilizamos break 2. Utilizamos o break com o valor de 2 dizendo para ele encerrar 2 níveis, sendo primeiro o looping de $j e depois o looping de $i.

Observe como seria se utilizássemos apenas o break.

<?php

for( $i = 1; $i <= 100; $i++ ){

  echo '<br />' . $i . '<br />' . PHP_EOL;
  echo 'Contando...';

  for( $j = $i + 1; $j <= $i + 5; $j++ ){

    if( $j != $i + 5 ){
      echo $j . ', ';
    } else {
      echo $j;
    }

    if($j == 7){
      break;
    }

  }

}


?>

Conseguimos encerrar o looping de $j quando fosse o valor 7 no entanto observe que o looping de $i é executado. Está é a utilidade de adicionar um valor ao break, pois assim você consegue encerrar quantos níveis forem necessários passando o valor para o break.

Em relação ao break:

  • É utilizado nos comandos for, foreach, falaremos deste posteriormente, while, do-while e switch.
  • Sua função é finalizar uma instrução, das citadas anteriormente.
  • Pode receber um valor adicional indicando quantos níveis devem ser encerrados.
  • Para o break receber um valor adicional o mesmo deve está dentro de uma estrutura aninhada

Continue

Bastante parecido com o break, a instrução continue permite que a execução do looping seja alterada, no entanto não encerramos o looping, apenas encerramos a iteração, volta do looping, atual e iniciamos a próxima.

Problema

  • Um looping for, predefinido terá que ser utilizado, este looping exibe os números de 1 a 100.
  • Dentro deste looping exiba apenas os números pares

No PHP

Veja a nossa possível solução para este problema no PHP.

<?php

for( $i = 1; $i <= 100; $i++ ){

  if( $i % 2 != 0 ){
    continue;
  }

  echo $i . '<br />' . PHP_EOL;

}


?>

Mantemos o looping do problema e dentro dele criamos um if em que se módulo de $i não for igual a 0, ou seja não é par, utilizamos o continue para irmos para próxima volta do looping.

Continue e o seu valor opcional

Assim como o break o continue também pode receber um valor opcional indicando quantos níveis devem ser encerrados. Lembrando que deve possuir estruturas de controle aninhadas.

Problema

  • Programa que escreva de 1 a 100
  • E abaixo de cada número exiba a frase “Contando...” e os 5 próximos números
  • Quando o número da contagem for igual a sete ele deve ser ignorado, se houver mais números depois dele não deve ser exibido também

No PHP

Veja como poderíamos resolver este problema:

<?php

for( $i = 1; $i <= 100; $i++ ){

  echo '<br />' . $i . '<br />' . PHP_EOL;
  echo 'Contando...';

  for( $j = $i + 1; $j <= $i + 5; $j++ ){

    if( $j == 7 ){
      continue 2;
    }

    if( $j != $i + 5 ){
      echo $j . ', ';
    } else {
      echo $j;
    }



  }

}


?>

Como você pode ver a lógica é a mesma que utilizamos no break 2, no entanto observe que usamos o continue com o valor 2. Sendo assim sempre que houver um 7 na contagem saímos do segundo looping e iniciamos no primeiro looping.

Observe como seria se utilizássemos apenas o continue:

<?php

for( $i = 1; $i <= 100; $i++ ){

  echo '<br />' . $i . '<br />' . PHP_EOL;
  echo 'Contando...';

  for( $j = $i + 1; $j <= $i + 5; $j++ ){

    if( $j == 7 ){
      continue;
    }

    if( $j != $i + 5 ){
      echo $j . ', ';
    } else {
      echo $j;
    }

  }

}


?>

Encerramos a iteração, a volta, do looping de $j quando o valor fosse igual a 7 no entanto retornamos para o looping de $j já com o valor do continue conseguimos encerrar quantos níveis forem necessários.

Em relação ao continue:

  • É utilizado nos comandos for, foreach, falaremos deste posteriormente, while, do-while e switch.
  • Sua função é finalizar uma iteração, volta, das citadas anteriormente.
  • Pode receber um valor adicional indicando quantos níveis o continue deve considerar para encerrar a iteração.
  • Para o continue receber um valor adicional o mesmo deve está dentro de uma estrutura aninhada

Comentários

comments powered by Disqus