Criar Calculadora de Fatorial em C

CBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como criar uma calculadora de fatorial na linguagem de programação C. O laboratório cobre tópicos essenciais, como a compreensão da sintaxe de laços for, a iteração sobre elementos de arrays, a implementação do cálculo do fatorial, o tratamento de casos extremos e o teste e depuração da calculadora de fatorial. Ao final deste laboratório, você terá uma sólida compreensão desses conceitos fundamentais de programação e será capaz de aplicá-los para construir uma calculadora de fatorial funcional.

O laboratório fornece instruções passo a passo e exemplos de código para guiá-lo no processo de criação da calculadora de fatorial. Você começará aprendendo a sintaxe básica de laços for, que são cruciais para iterar sobre arrays e realizar tarefas repetitivas. Em seguida, você explorará como acessar e manipular elementos de arrays, o que é essencial para o cálculo do fatorial. O laboratório também abordará a implementação do cálculo do fatorial, o tratamento de casos extremos e o teste e depuração do programa final.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível iniciante com uma taxa de conclusão de 100%. Recebeu uma taxa de avaliações positivas de 100% dos estudantes.

Entender a Sintaxe do Laço For

Nesta etapa, você aprenderá sobre a sintaxe fundamental dos laços for na programação C, que são essenciais para iterar sobre arrays e realizar tarefas repetitivas, como calcular fatoriais.

Vamos começar criando um programa C simples para demonstrar a sintaxe básica do laço for. Abra o WebIDE e crie um novo arquivo chamado loop_example.c no diretório ~/project:

cd ~/project
touch loop_example.c
#include <stdio.h>

int main() {
    // Sintaxe básica do laço for: for (inicialização; condição; incremento/decremento)
    for (int i = 0; i < 5; i++) {
        printf("Iteração atual: %d\n", i);
    }
    return 0;
}

Exemplo de saída:

Iteração atual: 0
Iteração atual: 1
Iteração atual: 2
Iteração atual: 3
Iteração atual: 4

Vamos detalhar a sintaxe do laço for:

  • int i = 0: Inicialização - define a variável do contador do laço para um valor inicial
  • i < 5: Condição - continua o laço enquanto esta condição for verdadeira
  • i++: Incremento - aumenta o contador do laço após cada iteração

Agora, compile e execute o programa para ver como o laço funciona:

gcc loop_example.c -o loop_example
./loop_example

O laço for é poderoso porque permite controlar o processo de iteração com precisão. Você pode modificar as partes de inicialização, condição e incremento/decremento para atender a diferentes necessidades de programação, como percorrer arrays ou realizar cálculos.

Iterar sobre os Elementos de um Array

Nesta etapa, você aprenderá como iterar sobre elementos de arrays em C, o que é crucial para implementar nossa calculadora de fatorial. Baseando-se no conhecimento do laço for da etapa anterior, exploraremos como acessar e manipular elementos de arrays.

Vamos criar um novo arquivo chamado array_iteration.c no diretório ~/project para demonstrar a iteração de arrays:

cd ~/project
touch array_iteration.c
#include <stdio.h>

int main() {
    // Declara e inicializa um array de inteiros
    int numbers[5] = {10, 20, 30, 40, 50};

    // Itera sobre o array usando um laço for
    for (int i = 0; i < 5; i++) {
        printf("Elemento no índice %d é: %d\n", i, numbers[i]);
    }

    return 0;
}

Exemplo de saída:

Elemento no índice 0 é: 10
Elemento no índice 1 é: 20
Elemento no índice 2 é: 30
Elemento no índice 3 é: 40
Elemento no índice 4 é: 50

Vamos detalhar os conceitos-chave:

  • int numbers[5] cria um array que pode armazenar 5 elementos inteiros
  • {10, 20, 30, 40, 50} inicializa o array com valores específicos
  • numbers[i] acessa elementos individuais do array usando o índice
  • O laço for usa i como um índice para acessar cada elemento sequencialmente

Agora, compile e execute o programa:

gcc array_iteration.c -o array_iteration
./array_iteration

Para tornar a iteração mais prática, vamos criar um exemplo que calcula a soma dos elementos do array:

#include <stdio.h>

int main() {
    int numbers[5] = {10, 20, 30, 40, 50};
    int sum = 0;

    // Calcula a soma usando a iteração do array
    for (int i = 0; i < 5; i++) {
        sum += numbers[i];
    }

    printf("Soma dos elementos do array: %d\n", sum);

    return 0;
}

Exemplo de saída:

Soma dos elementos do array: 150

Isso demonstra como você pode usar laços for para realizar operações em elementos de arrays, o que será crucial em nossa próxima implementação da calculadora de fatorial.

Implementar o Cálculo do Fatorial

Nesta etapa, você aprenderá como implementar uma função de cálculo de fatorial em C usando as técnicas de iteração de laço que você aprendeu nas etapas anteriores. Fatorial é uma operação matemática que multiplica um número por todos os inteiros positivos abaixo dele.

Vamos criar um novo arquivo chamado factorial_calculator.c no diretório ~/project:

cd ~/project
touch factorial_calculator.c
#include <stdio.h>

// Função para calcular o fatorial
int calculateFactorial(int n) {
    // Inicializa o resultado para 1
    int factorial = 1;

    // Usa o laço for para multiplicar os números de 1 a n
    for (int i = 1; i <= n; i++) {
        factorial *= i;
    }

    return factorial;
}

int main() {
    // Testa o cálculo do fatorial para diferentes números
    int numbers[] = {0, 1, 5, 7};

    // Itera sobre os números e calcula seus fatoriais
    for (int j = 0; j < 4; j++) {
        int num = numbers[j];
        int result = calculateFactorial(num);

        printf("Fatorial de %d é: %d\n", num, result);
    }

    return 0;
}

Exemplo de saída:

Fatorial de 0 é: 1
Fatorial de 1 é: 1
Fatorial de 5 é: 120
Fatorial de 7 é: 5040

Vamos detalhar o cálculo do fatorial:

  • Fatorial de 0 e 1 é 1
  • Fatorial de n (n!) = 1 2 3 ... n
  • A função calculateFactorial() usa um laço for para multiplicar números
  • Começamos o fatorial de 1 e multiplicamos por cada número até n

Compile e execute o programa:

gcc factorial_calculator.c -o factorial_calculator
./factorial_calculator

Para tornar a calculadora mais interativa, vamos modificar o programa para aceitar a entrada do usuário:

#include <stdio.h>

int calculateFactorial(int n) {
    int factorial = 1;
    for (int i = 1; i <= n; i++) {
        factorial *= i;
    }
    return factorial;
}

int main() {
    int number;

    // Solicita a entrada do usuário
    printf("Digite um número para calcular seu fatorial: ");
    scanf("%d", &number);

    // Calcula e exibe o fatorial
    int result = calculateFactorial(number);
    printf("Fatorial de %d é: %d\n", number, result);

    return 0;
}

Exemplo de interação:

Digite um número para calcular seu fatorial: 6
Fatorial de 6 é: 720

Lidar com Casos Extremos

Nesta etapa, você aprenderá como lidar com casos extremos em sua calculadora de fatorial, como números negativos e grandes entradas que podem causar integer overflow (estouro de inteiro). O tratamento robusto de erros é crucial para criar software confiável.

Vamos modificar nossa calculadora de fatorial para lidar com esses casos extremos. Crie um novo arquivo chamado factorial_edge_cases.c no diretório ~/project:

cd ~/project
touch factorial_edge_cases.c
#include <stdio.h>
#include <limits.h>

// Função para calcular o fatorial com tratamento de erros
int calculateFactorial(int n) {
    // Verifica se há números negativos
    if (n < 0) {
        printf("Erro: Fatorial não é definido para números negativos.\n");
        return -1;
    }

    // Inicializa o resultado para 1
    int factorial = 1;

    // Verifica a possibilidade de estouro de inteiro
    for (int i = 1; i <= n; i++) {
        // Verifica se a multiplicação causará estouro
        if (factorial > INT_MAX / i) {
            printf("Erro: O resultado do fatorial excede o limite do inteiro.\n");
            return -1;
        }
        factorial *= i;
    }

    return factorial;
}

int main() {
    // Testa vários casos extremos
    int test_cases[] = {-5, 0, 1, 12, 13};

    for (int i = 0; i < 5; i++) {
        int number = test_cases[i];
        int result = calculateFactorial(number);

        // Imprime o resultado apenas se o cálculo foi bem-sucedido
        if (result != -1) {
            printf("Fatorial de %d é: %d\n", number, result);
        }
    }

    return 0;
}

Exemplo de saída:

Erro: Fatorial não é definido para números negativos.
Fatorial de 0 é: 1
Fatorial de 1 é: 1
Fatorial de 12 é: 479001600
Erro: O resultado do fatorial excede o limite do inteiro.

Técnicas-chave de tratamento de erros:

  • Verifique se há números negativos antes do cálculo
  • Use INT_MAX para evitar integer overflow (estouro de inteiro)
  • Retorne -1 para indicar erro de cálculo
  • Forneça mensagens de erro informativas

Compile e execute o programa:

gcc factorial_edge_cases.c -o factorial_edge_cases
./factorial_edge_cases

Vamos aprimorar o programa com um tratamento de entrada mais amigável ao usuário:

#include <stdio.h>
#include <limits.h>

int calculateFactorial(int n) {
    if (n < 0) {
        printf("Erro: Fatorial não é definido para números negativos.\n");
        return -1;
    }

    int factorial = 1;

    for (int i = 1; i <= n; i++) {
        if (factorial > INT_MAX / i) {
            printf("Erro: O resultado do fatorial excede o limite do inteiro.\n");
            return -1;
        }
        factorial *= i;
    }

    return factorial;
}

int main() {
    int number;

    while (1) {
        printf("Digite um inteiro não negativo (ou negativo para sair): ");

        // Verifica se a entrada é válida
        if (scanf("%d", &number) != 1) {
            printf("Entrada inválida. Por favor, digite um inteiro.\n");
            // Limpa o buffer de entrada
            while (getchar() != '\n');
            continue;
        }

        // Condição de saída
        if (number < 0) {
            printf("Saindo da calculadora de fatorial.\n");
            break;
        }

        // Calcula e exibe o fatorial
        int result = calculateFactorial(number);
        if (result != -1) {
            printf("Fatorial de %d é: %d\n", number, result);
        }
    }

    return 0;
}

Exemplo de interação:

Digite um inteiro não negativo (ou negativo para sair): 10
Fatorial de 10 é: 3628800
Digite um inteiro não negativo (ou negativo para sair): -1
Saindo da calculadora de fatorial.

Testar e Depurar o Calculador de Fatorial

Nesta etapa final, você aprenderá como testar e depurar completamente sua calculadora de fatorial usando várias técnicas de teste e estratégias de depuração.

Vamos criar um programa de teste abrangente que inclui múltiplos casos de teste e recursos de depuração. Crie um arquivo chamado factorial_test.c no diretório ~/project:

cd ~/project
touch factorial_test.c
#include <stdio.h>
#include <assert.h>
#include <limits.h>

// Função de cálculo de fatorial com verificação detalhada de erros
int calculateFactorial(int n) {
    // Impressão de depuração para rastrear chamadas de função
    printf("DEBUG: Calculando fatorial para %d\n", n);

    // Valida a faixa de entrada
    if (n < 0) {
        fprintf(stderr, "ERROR: Fatorial indefinido para números negativos\n");
        return -1;
    }

    // Lida com casos especiais
    if (n == 0 || n == 1) return 1;

    // Cálculo de fatorial com proteção contra estouro
    long long factorial = 1;
    for (int i = 2; i <= n; i++) {
        factorial *= i;

        // Verificação de estouro
        if (factorial > INT_MAX) {
            fprintf(stderr, "ERROR: Fatorial excede o limite do inteiro\n");
            return -1;
        }
    }

    return (int)factorial;
}

// Função de teste para verificar os cálculos de fatorial
void runTests() {
    // Casos de teste com resultados esperados
    struct TestCase {
        int input;
        int expected;
    } tests[] = {
        {0, 1},    // Caso extremo: 0!
        {1, 1},    // Caso extremo: 1!
        {5, 120},  // Caso normal: 5!
        {10, 3628800}  // Número maior
    };

    int numTests = sizeof(tests) / sizeof(tests[0]);

    printf("Executando %d casos de teste...\n", numTests);

    // Itera pelos casos de teste
    for (int i = 0; i < numTests; i++) {
        int result = calculateFactorial(tests[i].input);

        // Teste no estilo de asserção
        if (result == tests[i].expected) {
            printf("Caso de teste %d PASSOU: factorial(%d) = %d\n",
                   i+1, tests[i].input, result);
        } else {
            printf("Caso de teste %d FALHOU: Esperado %d, Obtido %d\n",
                   i+1, tests[i].expected, result);
        }
    }
}

int main() {
    // Executa o conjunto de testes abrangente
    runTests();

    // Modo de teste interativo
    int number;
    printf("\nDigite um número para calcular seu fatorial (ou negativo para sair): ");
    while (scanf("%d", &number) == 1 && number >= 0) {
        int result = calculateFactorial(number);
        if (result != -1) {
            printf("Fatorial de %d é: %d\n", number, result);
        }

        printf("\nDigite outro número (ou negativo para sair): ");
    }

    return 0;
}

Compile e execute o programa:

gcc factorial_test.c -o factorial_test
./factorial_test

A saída de exemplo terá a seguinte aparência:

Executando 4 casos de teste...
DEBUG: Calculando fatorial para 0
Caso de teste 1 PASSOU: factorial(0) = 1
DEBUG: Calculando fatorial para 1
Caso de teste 2 PASSOU: factorial(1) = 1
DEBUG: Calculando fatorial para 5
Caso de teste 3 PASSOU: factorial(5) = 120
DEBUG: Calculando fatorial para 10
Caso de teste 4 PASSOU: factorial(10) = 3628800

Digite um número para calcular seu fatorial (ou negativo para sair):

Principais técnicas de depuração e teste demonstradas:

  • Declarações de impressão de depuração para rastrear a execução da função
  • Casos de teste abrangentes cobrindo casos extremos
  • Tratamento de erros para entradas inválidas
  • Proteção contra estouro
  • Teste no estilo de asserção
  • Modo de teste interativo

Dicas de depuração:

  1. Use printf() para registrar e rastrear chamadas de função
  2. Lide com casos extremos explicitamente
  3. Implemente a validação de entrada
  4. Use long long para cálculos de números maiores
  5. Crie um conjunto de testes para verificar diferentes cenários

Resumo

Neste laboratório, você aprendeu a sintaxe fundamental dos laços for na programação em C, que são essenciais para iterar sobre arrays e realizar tarefas repetitivas como calcular fatoriais. Você também explorou como iterar sobre elementos de um array, o que é crucial para implementar a calculadora de fatorial.

Você começou criando um programa C simples para demonstrar a sintaxe básica do laço for, compreendendo as partes de inicialização, condição e incremento/decremento do laço. Em seguida, você aprendeu como iterar sobre um array de inteiros usando um laço for, acessando e manipulando os elementos do array.