Create Factorial Calculator in C

CCBeginner
Practice Now

Introduction

In this lab, you will learn how to create a factorial calculator in C programming language. The lab covers essential topics such as understanding the syntax of for loops, iterating over array elements, implementing the factorial calculation, handling edge cases, and testing and debugging the factorial calculator. By the end of this lab, you will have a solid understanding of these fundamental programming concepts and be able to apply them to build a functional factorial calculator.

The lab provides step-by-step instructions and code examples to guide you through the process of creating the factorial calculator. You will start by learning the basic syntax of for loops, which are crucial for iterating through arrays and performing repetitive tasks. Then, you will explore how to access and manipulate array elements, which is essential for the factorial calculation. The lab will also cover the implementation of the factorial calculation, handling edge cases, and testing and debugging the final program.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("`C`")) -.-> c/UserInteractionGroup(["`User Interaction`"]) c(("`C`")) -.-> c/ControlFlowGroup(["`Control Flow`"]) c(("`C`")) -.-> c/CompoundTypesGroup(["`Compound Types`"]) c(("`C`")) -.-> c/FunctionsGroup(["`Functions`"]) c(("`C`")) -.-> c/BasicsGroup(["`Basics`"]) c/UserInteractionGroup -.-> c/output("`Output`") c/ControlFlowGroup -.-> c/for_loop("`For Loop`") c/CompoundTypesGroup -.-> c/arrays("`Arrays`") c/FunctionsGroup -.-> c/function_declaration("`Function Declaration`") c/BasicsGroup -.-> c/variables("`Variables`") subgraph Lab Skills c/output -.-> lab-438256{{"`Create Factorial Calculator in C`"}} c/for_loop -.-> lab-438256{{"`Create Factorial Calculator in C`"}} c/arrays -.-> lab-438256{{"`Create Factorial Calculator in C`"}} c/function_declaration -.-> lab-438256{{"`Create Factorial Calculator in C`"}} c/variables -.-> lab-438256{{"`Create Factorial Calculator in C`"}} end

Understand For Loop Syntax

In this step, you'll learn about the fundamental syntax of for loops in C programming, which are essential for iterating through arrays and performing repetitive tasks like calculating factorials.

Let's start by creating a simple C program to demonstrate the basic for loop syntax. Open the WebIDE and create a new file named loop_example.c in the ~/project directory:

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

int main() {
    // Basic for loop syntax: for (initialization; condition; increment/decrement)
    for (int i = 0; i < 5; i++) {
        printf("Current iteration: %d\n", i);
    }
    return 0;
}

Example output:

Current iteration: 0
Current iteration: 1
Current iteration: 2
Current iteration: 3
Current iteration: 4

Let's break down the for loop syntax:

  • int i = 0: Initialization - sets the loop counter variable to an initial value
  • i < 5: Condition - continues the loop while this condition is true
  • i++: Increment - increases the loop counter after each iteration

Now, compile and run the program to see how the loop works:

gcc loop_example.c -o loop_example
./loop_example

The for loop is powerful because it allows you to control the iteration process precisely. You can modify the initialization, condition, and increment/decrement parts to suit different programming needs, such as traversing arrays or performing calculations.

Iterate Over Array Elements

In this step, you'll learn how to iterate over array elements in C, which is crucial for implementing our factorial calculator. Building upon the previous step's for loop knowledge, we'll explore how to access and manipulate array elements.

Let's create a new file called array_iteration.c in the ~/project directory to demonstrate array iteration:

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

int main() {
    // Declare and initialize an array of integers
    int numbers[5] = {10, 20, 30, 40, 50};

    // Iterate through the array using a for loop
    for (int i = 0; i < 5; i++) {
        printf("Element at index %d is: %d\n", i, numbers[i]);
    }

    return 0;
}

Example output:

Element at index 0 is: 10
Element at index 1 is: 20
Element at index 2 is: 30
Element at index 3 is: 40
Element at index 4 is: 50

Let's break down the key concepts:

  • int numbers[5] creates an array that can hold 5 integer elements
  • {10, 20, 30, 40, 50} initializes the array with specific values
  • numbers[i] accesses individual array elements using the index
  • The for loop uses i as an index to access each element sequentially

Now, compile and run the program:

gcc array_iteration.c -o array_iteration
./array_iteration

To make the iteration more practical, let's create an example that calculates the sum of array elements:

#include <stdio.h>

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

    // Calculate sum using array iteration
    for (int i = 0; i < 5; i++) {
        sum += numbers[i];
    }

    printf("Sum of array elements: %d\n", sum);

    return 0;
}

Example output:

Sum of array elements: 150

This demonstrates how you can use for loops to perform operations on array elements, which will be crucial in our upcoming factorial calculator implementation.

Implement Factorial Calculation

In this step, you'll learn how to implement a factorial calculation function in C using the loop iteration techniques you've learned in previous steps. Factorial is a mathematical operation that multiplies a number by all positive integers below it.

Let's create a new file called factorial_calculator.c in the ~/project directory:

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

// Function to calculate factorial
int calculateFactorial(int n) {
    // Initialize result to 1
    int factorial = 1;

    // Use for loop to multiply numbers from 1 to n
    for (int i = 1; i <= n; i++) {
        factorial *= i;
    }

    return factorial;
}

int main() {
    // Test factorial calculation for different numbers
    int numbers[] = {0, 1, 5, 7};

    // Iterate through the numbers and calculate their factorials
    for (int j = 0; j < 4; j++) {
        int num = numbers[j];
        int result = calculateFactorial(num);

        printf("Factorial of %d is: %d\n", num, result);
    }

    return 0;
}

Example output:

Factorial of 0 is: 1
Factorial of 1 is: 1
Factorial of 5 is: 120
Factorial of 7 is: 5040

Let's break down the factorial calculation:

  • Factorial of 0 and 1 is 1
  • Factorial of n (n!) = 1 _ 2 _ 3 _ ... _ n
  • The calculateFactorial() function uses a for loop to multiply numbers
  • We start the factorial from 1 and multiply by each number up to n

Compile and run the program:

gcc factorial_calculator.c -o factorial_calculator
./factorial_calculator

To make the calculator more interactive, let's modify the program to accept user input:

#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;

    // Prompt user for input
    printf("Enter a number to calculate its factorial: ");
    scanf("%d", &number);

    // Calculate and display factorial
    int result = calculateFactorial(number);
    printf("Factorial of %d is: %d\n", number, result);

    return 0;
}

Example interaction:

Enter a number to calculate its factorial: 6
Factorial of 6 is: 720

Handle Edge Cases

In this step, you'll learn how to handle edge cases in your factorial calculator, such as negative numbers and large inputs that might cause integer overflow. Robust error handling is crucial for creating reliable software.

Let's modify our factorial calculator to handle these edge cases. Create a new file called factorial_edge_cases.c in the ~/project directory:

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

// Function to calculate factorial with error handling
int calculateFactorial(int n) {
    // Check for negative numbers
    if (n < 0) {
        printf("Error: Factorial is not defined for negative numbers.\n");
        return -1;
    }

    // Initialize result to 1
    int factorial = 1;

    // Check for potential integer overflow
    for (int i = 1; i <= n; i++) {
        // Check if multiplication will cause overflow
        if (factorial > INT_MAX / i) {
            printf("Error: Factorial result exceeds integer limit.\n");
            return -1;
        }
        factorial *= i;
    }

    return factorial;
}

int main() {
    // Test various edge cases
    int test_cases[] = {-5, 0, 1, 12, 13};

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

        // Only print result if calculation was successful
        if (result != -1) {
            printf("Factorial of %d is: %d\n", number, result);
        }
    }

    return 0;
}

Example output:

Error: Factorial is not defined for negative numbers.
Factorial of 0 is: 1
Factorial of 1 is: 1
Factorial of 12 is: 479001600
Error: Factorial result exceeds integer limit.

Key error handling techniques:

  • Check for negative numbers before calculation
  • Use INT_MAX to prevent integer overflow
  • Return -1 to indicate calculation error
  • Provide informative error messages

Compile and run the program:

gcc factorial_edge_cases.c -o factorial_edge_cases
./factorial_edge_cases

Let's enhance the program with more user-friendly input handling:

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

int calculateFactorial(int n) {
    if (n < 0) {
        printf("Error: Factorial is not defined for negative numbers.\n");
        return -1;
    }

    int factorial = 1;

    for (int i = 1; i <= n; i++) {
        if (factorial > INT_MAX / i) {
            printf("Error: Factorial result exceeds integer limit.\n");
            return -1;
        }
        factorial *= i;
    }

    return factorial;
}

int main() {
    int number;

    while (1) {
        printf("Enter a non-negative integer (or negative to exit): ");

        // Check if input is valid
        if (scanf("%d", &number) != 1) {
            printf("Invalid input. Please enter an integer.\n");
            // Clear input buffer
            while (getchar() != '\n');
            continue;
        }

        // Exit condition
        if (number < 0) {
            printf("Exiting factorial calculator.\n");
            break;
        }

        // Calculate and display factorial
        int result = calculateFactorial(number);
        if (result != -1) {
            printf("Factorial of %d is: %d\n", number, result);
        }
    }

    return 0;
}

Example interaction:

Enter a non-negative integer (or negative to exit): 10
Factorial of 10 is: 3628800
Enter a non-negative integer (or negative to exit): -1
Exiting factorial calculator.

Test and Debug Factorial Calculator

In this final step, you'll learn how to thoroughly test and debug your factorial calculator using various testing techniques and debugging strategies.

Let's create a comprehensive testing program that includes multiple test cases and debugging features. Create a file named factorial_test.c in the ~/project directory:

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

// Factorial calculation function with detailed error checking
int calculateFactorial(int n) {
    // Debug print to track function calls
    printf("DEBUG: Calculating factorial for %d\n", n);

    // Validate input range
    if (n < 0) {
        fprintf(stderr, "ERROR: Factorial undefined for negative numbers\n");
        return -1;
    }

    // Handle special cases
    if (n == 0 || n == 1) return 1;

    // Factorial calculation with overflow protection
    long long factorial = 1;
    for (int i = 2; i <= n; i++) {
        factorial *= i;

        // Overflow check
        if (factorial > INT_MAX) {
            fprintf(stderr, "ERROR: Factorial exceeds integer limit\n");
            return -1;
        }
    }

    return (int)factorial;
}

// Test function to verify factorial calculations
void runTests() {
    // Test cases with expected results
    struct TestCase {
        int input;
        int expected;
    } tests[] = {
        {0, 1},    // Edge case: 0!
        {1, 1},    // Edge case: 1!
        {5, 120},  // Normal case: 5!
        {10, 3628800}  // Larger number
    };

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

    printf("Running %d test cases...\n", numTests);

    // Iterate through test cases
    for (int i = 0; i < numTests; i++) {
        int result = calculateFactorial(tests[i].input);

        // Assertion-style testing
        if (result == tests[i].expected) {
            printf("Test case %d PASSED: factorial(%d) = %d\n",
                   i+1, tests[i].input, result);
        } else {
            printf("Test case %d FAILED: Expected %d, Got %d\n",
                   i+1, tests[i].expected, result);
        }
    }
}

int main() {
    // Run comprehensive test suite
    runTests();

    // Interactive testing mode
    int number;
    printf("\nEnter a number to calculate its factorial (or negative to exit): ");
    while (scanf("%d", &number) == 1 && number >= 0) {
        int result = calculateFactorial(number);
        if (result != -1) {
            printf("Factorial of %d is: %d\n", number, result);
        }

        printf("\nEnter another number (or negative to exit): ");
    }

    return 0;
}

Compile and run the program:

gcc factorial_test.c -o factorial_test
./factorial_test

Example output will look like:

Running 4 test cases...
DEBUG: Calculating factorial for 0
Test case 1 PASSED: factorial(0) = 1
DEBUG: Calculating factorial for 1
Test case 2 PASSED: factorial(1) = 1
DEBUG: Calculating factorial for 5
Test case 3 PASSED: factorial(5) = 120
DEBUG: Calculating factorial for 10
Test case 4 PASSED: factorial(10) = 3628800

Enter a number to calculate its factorial (or negative to exit):

Key debugging and testing techniques demonstrated:

  • Debug print statements to track function execution
  • Comprehensive test cases covering edge cases
  • Error handling for invalid inputs
  • Overflow protection
  • Assertion-style testing
  • Interactive testing mode

Debugging Tips:

  1. Use printf() for logging and tracking function calls
  2. Handle edge cases explicitly
  3. Implement input validation
  4. Use long long for larger number calculations
  5. Create a test suite to verify different scenarios

Summary

In this lab, you learned the fundamental syntax of for loops in C programming, which are essential for iterating through arrays and performing repetitive tasks like calculating factorials. You also explored how to iterate over array elements, which is crucial for implementing the factorial calculator.

You started by creating a simple C program to demonstrate the basic for loop syntax, understanding the initialization, condition, and increment/decrement parts of the loop. Then, you learned how to iterate through an array of integers using a for loop, accessing and manipulating the array elements.

Other C Tutorials you may like