As estruturas de repetição são fundamentais para executar blocos de código repetidamente com base em condições. Nesta aula, vamos explorar as construções while, do-while e do-until no PowerShell, que permitem criar loops flexíveis e controlados. Você aprenderá como cada uma funciona, quando usar cada uma e como interromper ou pular iterações com break e continue.

Diferentemente do loop for, que é ideal quando se sabe o número de iterações, os loops baseados em condição são mais adequados para situações em que a repetição depende de uma expressão lógica que pode mudar durante a execução. Vamos detalhar cada tipo.

while

O loop while executa um bloco de comandos enquanto uma condição especificada for verdadeira. A condição é avaliada antes de cada iteração; se for $true, o bloco é executado; se for $false, o loop termina. É possível que o bloco nunca seja executado se a condição inicial já for falsa.

Sintaxe básica:

while (condição) {
    # comandos
}

Exemplo prático: contar de 1 a 5.

$i = 1
while ($i -le 5) {
    Write-Host "Número: $i"
    $i++
}

Neste exemplo, a condição $i -le 5 é verificada a cada início de iteração. Enquanto for verdadeira, o bloco é executado e o valor de $i é incrementado. Quando $i chega a 6, a condição se torna falsa e o loop termina.

do-while e do-until

O do-while é semelhante ao while, mas a condição é avaliada após a execução do bloco, garantindo que o bloco seja executado pelo menos uma vez. A sintaxe é:

do {
    # comandos
} while (condição)

Exemplo: ler entrada do usuário até que ele digite "sair".

do {
    $entrada = Read-Host "Digite algo (ou 'sair' para encerrar)"
    Write-Host "Você digitou: $entrada"
} while ($entrada -ne 'sair')

Já o do-until é o inverso do do-while: executa o bloco até que a condição se torne verdadeira. Ou seja, repete enquanto a condição for falsa. Sintaxe:

do {
    # comandos
} until (condição)

Exemplo: gerar números aleatórios até obter um maior que 0.9.

do {
    $num = Get-Random -Minimum 0.0 -Maximum 1.0
    Write-Host "Número gerado: $num"
} until ($num -gt 0.9)

Note que a condição do until é a condição de parada; quando ela se torna verdadeira, o loop termina. Portanto, o comportamento é equivalente a do-while com a condição negada.

break e continue

Os comandos break e continue permitem controlar o fluxo dentro de loops. break encerra imediatamente o loop, enquanto continue pula o restante do bloco atual e vai para a próxima iteração (avaliando a condição novamente, no caso de while e do-while).

Exemplo com break: percorrer uma lista e parar ao encontrar um valor específico.

$nomes = @('Ana', 'Bruno', 'Carlos', 'Diana')
foreach ($nome in $nomes) {
    if ($nome -eq 'Carlos') {
        Write-Host "Encontrado: $nome"
        break
    }
    Write-Host "Verificando: $nome"
}

Exemplo com continue: exibir apenas números pares de 1 a 10.

$i = 0
while ($i -lt 10) {
    $i++
    if ($i % 2 -ne 0) {
        continue  # pula ímpares
    }
    Write-Host "Par: $i"
}

Esses comandos são úteis para evitar aninhamentos profundos ou para sair de loops sob condições excepcionais.

Casos de uso

Os loops while e do são ideais para situações onde o número de iterações não é conhecido antecipadamente. Exemplos comuns incluem:

  • Leitura de arquivos linha por linha: até o final do arquivo.
  • Processamento de filas: enquanto houver itens na fila.
  • Validação de entrada: repetir até que o usuário forneça um valor válido.
  • Simulações: executar até que uma condição de convergência seja atingida.
  • Menus interativos: exibir opções até que o usuário escolha sair.

Exemplo de menu simples:

do {
    Write-Host "`nMenu:"
    Write-Host "1. Opção A"
    Write-Host "2. Opção B"
    Write-Host "3. Sair"
    $opcao = Read-Host "Escolha uma opção"
    switch ($opcao) {
        '1' { Write-Host "Você escolheu A" }
        '2' { Write-Host "Você escolheu B" }
        '3' { Write-Host "Saindo..." }
        default { Write-Host "Opção inválida" }
    }
} until ($opcao -eq '3')

Neste caso, o loop garante que o menu seja exibido pelo menos uma vez e continua até que o usuário escolha sair.

Boas práticas

  • Evite loops infinitos: certifique-se de que a condição se tornará falsa em algum momento.
  • Use break e continue com moderação para não dificultar a legibilidade.
  • Prefira while quando a condição deve ser verificada antes da primeira execução; use do-while ou do-until quando o bloco precisa executar ao menos uma vez.
  • Para condições de parada, do-until pode ser mais intuitivo se a lógica for "repita até que algo aconteça".

Referências

Exercícios

  1. Escreva um script que use um loop while para exibir os números de 10 a 1 (ordem decrescente).

    ✓ Resposta:
    $i = 10
    while ($i -ge 1) {
        Write-Host $i
        $i--
    }
  2. Crie um script com do-while que peça ao usuário para adivinhar um número secreto (por exemplo, 7) e continue até acertar.

    ✓ Resposta:
    $segredo = 7
    do {
        $palpite = Read-Host "Adivinhe o número (1-10)"
        if ($palpite -ne $segredo) {
            Write-Host "Errou! Tente novamente."
        }
    } while ($palpite -ne $segredo)
    Write-Host "Parabéns! Você acertou."
  3. Use do-until para gerar números aleatórios entre 1 e 100 até que um número seja divisível por 7 e por 3 ao mesmo tempo. Exiba cada número gerado.

    ✓ Resposta:
    do {
        $num = Get-Random -Minimum 1 -Maximum 101
        Write-Host "Gerado: $num"
    } until (($num % 7 -eq 0) -and ($num % 3 -eq 0))
    Write-Host "Número encontrado: $num"
  4. Escreva um script que percorra uma lista de números de 1 a 20 usando while e use continue para pular os múltiplos de 3, exibindo apenas os demais.

    ✓ Resposta:
    $i = 1
    while ($i -le 20) {
        if ($i % 3 -eq 0) {
            $i++
            continue
        }
        Write-Host $i
        $i++
    }
  5. Crie um loop while infinito (com condição sempre verdadeira) que leia comandos do usuário e use break para sair quando o comando for "quit".

    ✓ Resposta:
    while ($true) {
        $cmd = Read-Host "Digite um comando (ou 'quit' para sair)"
        if ($cmd -eq 'quit') {
            break
        }
        Write-Host "Executando: $cmd"
    }