Laço

Quatro tipos de laços: for / while / repeat / for-in

Primeiro, veja os exemplos abaixo. Modifique o arquivo de código da aula anterior, mydemo.dpr, e altere sua extensão para pas, resultando em mydemo.pas. Esta é a extensão padrão para arquivos de código-fonte Pascal. Em seguida, baixe um editor de código com destaque de sintaxe, como o Notepad++, que deixará o código muito mais legível.

Abaixo segue um exemplo completo com comentários linha por linha. Após o código, explicaremos cada instrução passo a passo.

// 2.8 Instruções de laço: for, while, repeat, for..in
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
// Diretivas do compilador FPC: ativar modo orientado a objetos, strings longas, desativar contagem automática de referência de strings
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
// Plataforma Windows: definir o programa como aplicativo de console (sem janela gráfica)
{$R+} // Ativar verificação de limites de vetor, muito útil para depurar erros de índice
var
  MyArray: array [0..9] of Integer; // Vetor de inteiros com 10 elementos, índices de 0 a 9
  I: Integer; // Variável contadora do laço
begin
// 1. Laço for crescente: inicializar o vetor com os quadrados dos números de 0 a 9
for I := 0 to 9 do
    MyArray[I] := I * I;

// 2. Laço for básico para percorrer índices e imprimir os quadrados
for I := 0 to 9 do
    WriteLn('O quadrado é ', MyArray[I]);

// 3. Low/High obtêm automaticamente os limites do vetor, sem valores fixos 0 e 9, maior escalabilidade
for I := Low(MyArray) to High(MyArray) do
    WriteLn('O quadrado é ', MyArray[I]);

// 4. Laço while: verifica a condição primeiro, executa o corpo apenas se a condição for verdadeira
  I := 0;
while I < 10 do
begin
    WriteLn('O quadrado é ', MyArray[I]);
    I := I + 1; // Três formas equivalentes: I+=1 / Inc(I)
end;

// 5. Laço repeat-until: executa o corpo uma vez primeiro, verifica a condição de saída no final
  I := 0;
repeat
    WriteLn('O quadrado é ', MyArray[I]);
    Inc(I); // Incrementar contador
until I = 10;

// 6. Iteração for-in: captura diretamente os valores dos elementos sem manipular índices
for I in MyArray do
    WriteLn('O quadrado é ', I);
end.Code language: PHP (php)

Abaixo está o código sem nenhum comentário

{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

var
  MyArray: array [0..9] of Integer;
  I: Integer;

begin

for I := 0 to 9 do
    MyArray[I] := I * I;

for I := 0 to 9 do
    WriteLn('O quadrado é ', MyArray[I]);

for I := Low(MyArray) to High(MyArray) do
    WriteLn('O quadrado é ', MyArray[I]);

  I := 0;
while I < 10 do
begin
    WriteLn('O quadrado é ', MyArray[I]);
    I := I + 1;
end;

  I := 0;
repeat
    WriteLn('O quadrado é ', MyArray[I]);
    Inc(I);
until I = 10;

for I in MyArray do
    WriteLn('O quadrado é ', I);

end.Code language: PHP (php)

Agora analisaremos o código de cada laço de forma sequencial

Laço for

Atribuir valores a um vetor usando um laço for

{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

var
  MyArray: array [0..9] of Integer;
  I: Integer;

begin

for I := 0 to 9 do
    MyArray[I] := I * I;

end.Code language: PHP (php)

Este código é dividido em três partes: diretivas de pré-compilação no topo, seção var para declarar variáveis (um vetor e um inteiro), e o bloco principal de execução entre begin e end., contendo um laço for que atribui sequencialmente valores de 0 a 9 à variável I para preencher os elementos do vetor via índice.

Preenchemos os dez elementos MyArray[0] até MyArray[9]. O asterisco * é o operador de multiplicação.

MyArray[0] := 0 * 0;

MyArray[1] := 1 * 1;

MyArray[9] := 9 * 9;

Em seguida, adicione outro laço for abaixo do primeiro para ler cada valor armazenado no vetor.

Após compilar e executar, todos os valores serão exibidos na saída

Todos os resultados são os quadrados de 0 a 9, compatíveis com nossas expectativas anteriores.

Se você não souber o intervalo de índices do vetor, use funções nativas para obter os limites inferior e superior.

A função Low(NomeVetor) acima retorna o menor índice do vetor

  • Low(Tipo/Variável): obtém o valor mínimo / limite inferior de tipos ordinais, vetores, conjuntos
  • High(Tipo/Variável): obtém o valor máximo / limite superior de tipos ordinais, vetores, conjuntos

Laços while e repeat

Dentro do corpo do laço while delimitado por begin end;, a variável I recebe incremento de 1 no final do bloco. Após o incremento, o fluxo retorna para a linha while I < 10 do para nova verificação. Se a condição for verdadeira, o corpo roda novamente, I incrementa mais uma vez e o teste se repete. O ciclo encerra quando I < 10 se tornar falso, ou seja, quando I valer 10.

Diferenças centrais entre while e repeat-until

  1. Lógica de condição oposta
  • while Condição do: condição verdadeira → continuar laço; condição falsa → sair
  • repeat ... until Condição: condição verdadeira → sair; condição falsa → continuar laço
  1. Garantia de execução distinta
  • while: se a condição inicial for falsa, o corpo do laço nunca executa
  • repeat-until: independente da condição, o corpo executa no mínimo uma vez

Se você já estudou linguagens como C, C++ ou Java, fica fácil entender: repeat-until tem funcionamento idêntico ao do-while. Executa o corpo uma vez primeiro, depois verifica a condição após until; se for falsa, repete o laço.

repeat-until não precisa de begin e end, pois repeat e until formam naturalmente um bloco único. Você pode adicionar begin end manualmente, mas não é recomendado.

O significado literal de repeat-until é “repetir … até que”, o funcionamento é intuitivo pelo próprio nome.


Durante a iteração, os valores armazenados em MyArray são atribuídos sequencialmente a I, podendo manipular I diretamente dentro do laço. Não é preciso incrementar índices manualmente, nem mesmo usar índices, até percorrer todos os elementos.

Explicação do laço for padrão (for I := ... to/downto)

  1. Análogo ao laço for da linguagem C, porém com restrições mais rígidas: só percorre valores ordinais contínuos (inteiros, enumerações);
  2. Suporta varredura inversa com downto: for I := 9 downto 0 do;
  3. Os limites Low(xx) / High(xx) são calculados apenas uma vez no início do laço, garantindo alta performance;
  4. Ao término normal do laço, o valor da variável I é indefinido e o compilador emite aviso. Se sair antecipadamente com Break ou Exit, I mantém seu valor atual.

Iteração for-in (estilo foreach moderno)

Permite percorrer quatro tipos de dados sem manipular índices manualmente:

  1. Vetores: ler diretamente cada valor de elemento (demonstrado nos exemplos anteriores)
  2. Tipos enumerados
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$R+}

type TAnimalKind = (Duck,Cat,Dog);

var AK:TAnimalKind;
begin
  for AK in TAnimalKind do 
    WriteLn(AK);
end.Code language: PHP (php)
  1. Tipos conjunto
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}

type
  // Definir tipo enumerado
  TAnimalKind = (Duck, Cat, Dog);
  // Definir tipo conjunto baseado na enumeração
  TAnimals = set of TAnimalKind;

var
  Animals: TAnimals;
  AK: TAnimalKind;
begin
  // Atribuir dois valores enumerados ao conjunto: Duck e Cat
  Animals := [Duck, Cat];

  // Iterar todos os membros presentes no conjunto via for-in
  for AK in Animals do
  begin
    WriteLn('Animal encontrado: ', AK);
  end;
end.Code language: PHP (php)
  1. Listas genéricas (estudado nos capítulos posteriores)
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
uses
  SysUtils, Generics.Collections; // Importar unidade de contêineres genéricos

type
  TMyClass = class  // Classe personalizada para armazenar número e seu quadrado
    I, Square: Integer;
  end;
  // Instanciar lista genérica de objetos com gerenciamento automático de ciclo de vida
  TMyClassList = {$ifdef FPC}specialize{$endif} TObjectList&lt;TMyClass&gt;;
var
  List: TMyClassList;
  C: TMyClass;
  I: Integer;
begin
  List := TMyClassList.Create(true); // true: liberar objetos internos ao destruir a lista
try
  // Criar objetos em laço e adicionar à lista
for I := 0 to 9 do
begin
      C := TMyClass.Create;
      C.I := I;
      C.Square := I * I;
      List.Add(C);
end;
  // Iterar diretamente cada objeto personalizado da lista com for-in
for C in List do
      WriteLn('O quadrado de ', C.I, ' é ', C.Square);
finally
    FreeAndNil(List); // Liberar lista com segurança para evitar vazamento de memória
end;
end.
Code language: HTML, XML (xml)

Observação: este exemplo usa classes e genéricos. Iniciantes podem ignorá-lo temporariamente; será detalhado no capítulo de programação orientada a objetos.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *