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, conjuntosHigh(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
- Lógica de condição oposta
while Condição do: condição verdadeira → continuar laço; condição falsa → sairrepeat ... until Condição: condição verdadeira → sair; condição falsa → continuar laço
- 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)
- 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);
- Suporta varredura inversa com downto:
for I := 9 downto 0 do; - Os limites Low(xx) / High(xx) são calculados apenas uma vez no início do laço, garantindo alta performance;
- 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:
- Vetores: ler diretamente cada valor de elemento (demonstrado nos exemplos anteriores)
- 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)

- 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)

- 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<TMyClass>;
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.