Loops: for, while e do-while

1. Introdução aos Loops em C

Em programação, loops (ou laços de repetição) são estruturas fundamentais que permitem executar um bloco de código múltiplas vezes. Esse conceito, chamado de iteração, evita a repetição manual de instruções e torna o código mais enxuto e eficiente.

Os loops podem ser classificados de duas formas principais:
- Controlados por contador: quando sabemos exatamente quantas vezes o bloco deve ser executado.
- Controlados por condição: quando a repetição depende de uma condição que pode mudar durante a execução.

A linguagem C oferece três tipos de loop: while, do-while e for. Cada um possui características específicas que os tornam mais adequados para determinadas situações. Vamos explorá-los em detalhes.

2. O Loop while

A sintaxe do while é simples e direta:

while (condição) {
    // bloco de código
}

O funcionamento é claro: a condição é testada antes da execução do bloco. Se for verdadeira, o bloco é executado; após a execução, a condição é testada novamente. Se for falsa desde o início, o bloco nunca será executado.

Exemplo 1: Contagem regressiva

#include <stdio.h>

int main() {
    int contador = 10;

    while (contador > 0) {
        printf("%d ", contador);
        contador--;
    }
    printf("Fim!\n");

    return 0;
}

Saída: 10 9 8 7 6 5 4 3 2 1 Fim!

Exemplo 2: Leitura de dados até flag

#include <stdio.h>

int main() {
    int numero, soma = 0;

    printf("Digite números (0 para sair): ");
    scanf("%d", &numero);

    while (numero != 0) {
        soma += numero;
        scanf("%d", &numero);
    }

    printf("Soma total: %d\n", soma);
    return 0;
}

Neste caso, o loop continua enquanto o usuário não digitar 0 (a flag de parada).

3. O Loop do-while

O do-while é semelhante ao while, mas com uma diferença crucial: a condição é testada após a execução do bloco. Isso garante que o bloco seja executado ao menos uma vez.

do {
    // bloco de código
} while (condição);

Exemplo: Menu interativo

#include <stdio.h>

int main() {
    int opcao;

    do {
        printf("\n=== MENU ===\n");
        printf("1 - Opção A\n");
        printf("2 - Opção B\n");
        printf("3 - Sair\n");
        printf("Escolha: ");
        scanf("%d", &opcao);

        switch (opcao) {
            case 1:
                printf("Você escolheu A\n");
                break;
            case 2:
                printf("Você escolheu B\n");
                break;
            case 3:
                printf("Saindo...\n");
                break;
            default:
                printf("Opção inválida!\n");
        }
    } while (opcao != 3);

    return 0;
}

Aqui, o menu deve ser exibido pelo menos uma vez antes de verificar se o usuário deseja sair. Com while, seria necessário duplicar o código do menu ou usar uma variável de controle extra.

4. O Loop for

O for é o loop mais completo e estruturado. Sua sintaxe reúne três componentes essenciais em uma única linha:

for (inicialização; condição; incremento) {
    // bloco de código
}
  • Inicialização: executada uma vez no início, geralmente para declarar e inicializar o contador.
  • Condição: testada antes de cada iteração; se verdadeira, o bloco é executado.
  • Incremento: executado ao final de cada iteração, geralmente para atualizar o contador.

Exemplo 1: Percorrendo um array

#include <stdio.h>

int main() {
    int numeros[] = {10, 20, 30, 40, 50};
    int tamanho = 5;

    for (int i = 0; i < tamanho; i++) {
        printf("Elemento %d: %d\n", i, numeros[i]);
    }

    return 0;
}

Exemplo 2: Tabuada do 7

#include <stdio.h>

int main() {
    int numero = 7;

    for (int i = 1; i <= 10; i++) {
        printf("%d x %d = %d\n", numero, i, numero * i);
    }

    return 0;
}

Quando o número de iterações é conhecido antecipadamente, o for é a escolha mais clara e idiomática.

5. Controle de Fluxo dentro de Loops

Duas instruções especiais permitem alterar o fluxo normal de um loop:

break

Interrompe imediatamente o loop, independentemente da condição.

Exemplo: Busca em vetor

#include <stdio.h>

int main() {
    int vetor[] = {3, 7, 12, 9, 5, 18, 2};
    int alvo = 9;
    int encontrado = 0;

    for (int i = 0; i < 7; i++) {
        if (vetor[i] == alvo) {
            printf("Elemento encontrado no índice %d\n", i);
            encontrado = 1;
            break;  // interrompe a busca
        }
    }

    if (!encontrado) {
        printf("Elemento não encontrado\n");
    }

    return 0;
}

continue

Pula o restante do bloco atual e vai para a próxima iteração.

Exemplo: Filtrando valores pares

#include <stdio.h>

int main() {
    for (int i = 1; i <= 10; i++) {
        if (i % 2 != 0) {
            continue;  // pula ímpares
        }
        printf("%d ", i);
    }
    printf("\n");

    return 0;
}

Saída: 2 4 6 8 10

6. Loops Aninhados

É possível colocar um loop dentro de outro. Isso é comum ao trabalhar com matrizes bidimensionais ou gerar combinações.

Exemplo: Matriz 3x3

#include <stdio.h>

int main() {
    int matriz[3][3] = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", matriz[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Exemplo: Tabela de multiplicação (10x10)

#include <stdio.h>

int main() {
    for (int i = 1; i <= 10; i++) {
        for (int j = 1; j <= 10; j++) {
            printf("%4d", i * j);
        }
        printf("\n");
    }

    return 0;
}

Cuidado com loops aninhados profundos, pois a complexidade cresce rapidamente e pode afetar o desempenho.

7. Erros Comuns e Boas Práticas

Loop infinito acidental: ocorre quando a condição nunca se torna falsa.

// ERRADO: contador nunca é incrementado
int i = 0;
while (i < 10) {
    printf("%d ", i);
    // falta i++;
}

Variáveis de controle não atualizadas: esquecer de modificar a variável que controla a condição.

Escopo de variáveis: declarar o contador dentro do for (como int i) limita seu escopo ao loop, evitando efeitos colaterais.

Preferência por for quando o número de iterações é conhecido: isso torna a intenção do código mais clara e reduz a chance de erros.

8. Comparação e Escolha do Loop Adequado

Característica while do-while for
Sintaxe while (cond) { } do { } while (cond); for (init; cond; inc) { }
Teste da condição Antes da execução Depois da execução Antes da execução
Execução garantida? Não Sim (ao menos uma vez) Não
Uso típico Repetição baseada em condição variável Menus, validação de entrada Iteração com contador definido

Quando usar cada um:

  • while: quando a repetição depende de uma condição que pode mudar durante a execução, como ler dados até encontrar um valor específico.
  • do-while: quando o bloco precisa ser executado ao menos uma vez, como em menus interativos ou validação de entrada do usuário.
  • for: quando o número de iterações é conhecido ou facilmente determinável, como percorrer arrays ou gerar sequências numéricas.

Dominar esses três tipos de loop é essencial para escrever código eficiente e legível em C. A escolha correta depende do contexto e da intenção do algoritmo.

Referências