Documento: Estruturas de Repetição


Dentro de uma rotina, frequentemente há a necessidade de repetirmos uma sequência ou bloco de instruções por uma quantidade de vezes, em geral desconhecida. Esta necessidade requer um comando que execute as instruções até que ocorra uma condição no processamento que a interrompa. Este comando é o WHILE ... ENDDO, que significa "execute enquanto". Ele executa repetidamente um bloco de instruções que esteja contido entre o seu início (WHILE) e o seu fim (ENDDO) enquanto uma determinada condição permanecer verdadeira. Por exemplo:

// Chamada da função de cálculo
FUNCTION Main()

LOCAL aEstoque := { { 300, "S" }, { 900, "S" }, { 400, "N" }, { 150, "N" }, { 540, "N" } }
LOCAL nReserva := 0

IF !EMPTY(aEstoque)
               nReserva := CalcGrao(1900, aEstoque)
ENDIF

RETURN NIL

// Função de cálculo
FUNCTION CalcGrao(nSacas, aAlmox)

LOCAL nPos := 1
LOCAL nReserva := 0
LOCAL nSoma := 0

WHILE nPos <= LEN(aAlmox) .AND. nReserva < nSacas
               nSoma := nReserva + aAlmox[nPos, 1]

               IF nSoma <= nSacas
                         nReserva := nSoma
               ELSE
                         nReserva := nSacas
               ENDIF

               nPos++
ENDDO
 
RETURN nReserva

Por vezes, é necessário interromper a execução das instruções contidas dentro do WHILE antes que se chegue ao final. Para isso, utiliza-se o comando LOOP. Esse comando permite a interrupção lógica do comando WHILE, voltando o fluxo de execução para o início do mesmo. Vejamos o exemplo abaixo:

// Função de cálculo
FUNCTION CalcGrao(nSacas, aAlmox)

LOCAL nPos := 0
LOCAL nReserva := 0
LOCAL nSoma := 0

WHILE nPos < LEN(aAlmox) .AND. nReserva < nSacas
               nPos++

               IF aAlmox[nPos, 2] == "N"
                         LOOP
               ENDIF

               nSoma := nReserva + aAlmox[nPos]

               IF nSoma <= nSacas
                         nReserva := nSoma
               ELSE
                         nReserva := nSacas
               ENDIF
ENDDO
 
RETURN nReserva

Ou seja, quando o conteúdo da 2ª informação do array for "N", o programa retornará ao início do WHILE e processará o próximo elemento. Portanto, os elementos com "N" não serão considerados no processamento.

Outra maneira de interromper a repetição do comando WHILE é por meio do comando EXIT (Saída). Este comando é semelhante ao LOOP. Porém, ao invés de retornar para o início do WHILE, a execução das instruções é finalizada, saindo do elo de repetição do WHILE. Dessa forma, a execução das instruções continuará depois do ENDDO. Por exemplo:

// Função de cálculo
FUNCTION CalcGrao(nSacas, aAlmox)

LOCAL nPos := 0
LOCAL nReserva := 0
LOCAL nSoma := 0

WHILE nPos < LEN(aAlmox) .AND. nReserva < nSacas
               nPos++

               IF aAlmox[nPos, 2] == "N"
                         EXIT
               ENDIF

               nSoma := nReserva + aAlmox[nPos]

               IF nSoma <= nSacas
                         nReserva := nSoma
               ELSE
                         nReserva := nSacas
               ENDIF
ENDDO
 
RETURN nReserva

Muitas vezes, também é necessário repetir um bloco de instruções por uma determinada quantidade de vezes. Para atender essa necessidade, requer-se um comando que execute um bloco de instruções de acordo com um contador que controle o número de vezes no qual o mesmo já foi executado e finalize a execução quando esse limite previsto é atingido. Este comando é o FOR ... NEXT. Ele repete a execução do bloco de instruções que estiver entre o seu início e o seu fim até que um contador atinja o limite especificado, de acordo com determinado incremento. Por exemplo:

// Função de cálculo
FUNCTION CalcGrao(nSacas, aAlmox)

LOCAL nPos := 0
LOCAL nReserva := 0
LOCAL nSoma := 0

FOR nPos := 1 TO LEN(aAlmox)
               nSoma := nReserva + aAlmox[nPos, 1]

               IF nSoma <= nSacas
                         nReserva := nSoma
               ELSE
                         nReserva := nSacas
               ENDIF
NEXT nPos
 
RETURN nReserva

Assim como o comando WHILE, o comando FOR ... NEXT também aceita o comando EXIT, que interrompe as repetições mesmo que o contador ainda não tenha chegado ao limite especificado. Vejamos o exemplo:

// Função de cálculo
FUNCTION CalcGrao(nSacas, aAlmox)

LOCAL nPos := 0
LOCAL nReserva := 0
LOCAL nSoma := 0

FOR nPos := 1 TO LEN(aAlmox)
               IF nReserva == nSacas .OR. aAlmox[nPos, 2] == "N"
                         EXIT
               ENDIF

               nSoma := nReserva + aAlmox[nPos, 1]

               IF nSoma <= nSacas
                         nReserva := nSoma
               ELSE
                         nReserva := nSacas
               ENDIF
NEXT nPos
 
RETURN nReserva

 

  • Sem rótulos