Resolução de Problema: Números Primos com for

Lógica de Programação e Algoritmos • Prof. Me. William Tenório

O problema

Dado um número inteiro, verificar se ele é primo.

Antes de escrever qualquer linha de código, precisamos entender bem o problema. Um número primo é um número inteiro maior que 1 que possui exatamente dois divisores: o número 1 e ele mesmo.

Lembrete: o que é "dividir exatamente"? Dizemos que d é divisor de n quando a divisão de n por d não deixa resto. Em C, verificamos isso com o operador de resto: n % d == 0 — a mesma ideia usada no exercício de par ou ímpar (numero % 2 == 0).

Pensando na lógica

Se a definição de primo é "ter exatamente dois divisores", uma forma direta de resolver o problema é: contar quantos divisores o número tem. Para isso, testamos todos os candidatos a divisor, de 1 até o próprio número, um por um:

  1. Ler o número n.
  2. Começar um contador de divisores valendo 0.
  3. Para cada valor i de 1 até n: se n % i == 0, somar 1 ao contador.
  4. Ao final, se o contador for igual a 2, o número é primo; caso contrário, não é.

O passo 3 é uma repetição com início e fim bem definidos (de 1 até n) — situação perfeita para o laço for.

Versão 1 — Verificar se um número é primo

#include <stdio.h>

int main() {
    int n, i;
    int divisores = 0;

    printf("Digite um numero inteiro: ");
    scanf("%d", &n);

    for (i = 1; i <= n; i++) {
        if (n % i == 0) {
            divisores++;
        }
    }

    if (divisores == 2) {
        printf("%d e primo\n", n);
    } else {
        printf("%d nao e primo\n", n);
    }

    return 0;
}

Explicando o código:

Teste de mesa com n = 7:

i7 % iÉ divisor?divisores
10sim1
21não1
31não1
43não1
52não1
61não1
70sim2

Ao final, divisores == 2, portanto 7 é primo.

Teste de mesa com n = 6:

i6 % iÉ divisor?divisores
10sim1
20sim2
30sim3
42não3
51não3
60sim4

Ao final, divisores == 4, portanto 6 não é primo.

E os casos especiais? Para n = 1, o laço encontra só um divisor, então o programa diz corretamente que 1 não é primo. Para n = 0 ou números negativos, o laço nem executa (a condição i <= n já começa falsa), o contador fica em 0 e o programa também responde "não é primo" — o que está correto, pois primos são sempre maiores que 1.

Desafios:

Versão 2 — Todos os primos entre 2 e N

Escreva um programa em C que leia um número inteiro N, maior que 1, e exiba todos os números primos entre 2 e N.

Já sabemos verificar se um número é primo. Agora precisamos fazer essa mesma verificação para cada número de 2 até N. Ou seja: vamos repetir a Versão 1 inteira várias vezes. Isso nos leva a um laço dentro de outro laço (laços aninhados):

#include <stdio.h>

int main() {
    int n, num, i;
    int divisores;

    printf("Digite um numero inteiro maior que 1: ");
    scanf("%d", &n);

    printf("Primos entre 2 e %d:\n", n);

    for (num = 2; num <= n; num++) {
        divisores = 0;

        for (i = 1; i <= num; i++) {
            if (num % i == 0) {
                divisores++;
            }
        }

        if (divisores == 2) {
            printf("%d\n", num);
        }
    }

    return 0;
}

Explicando o código:

Exemplo de execução com N = 20:

Digite um numero inteiro maior que 1: 20
Primos entre 2 e 20:
2
3
5
7
11
13
17
19
Resolver um problema a partir de outro Repare na estratégia: primeiro resolvemos um problema menor (verificar um número) e testamos até ter certeza de que funcionava. Depois, reaproveitamos essa solução dentro de uma repetição para resolver o problema maior. Quebrar um problema em partes menores é uma das habilidades mais importantes da programação.

Desafios:

Para refletir

A lógica usada aqui é a mais simples possível: testa todos os candidatos a divisor. Ela funciona, mas faz trabalho desnecessário. Pense: