C 언어로 팩토리얼 계산기 만들기

CBeginner
지금 연습하기

소개

이 랩에서는 C 프로그래밍 언어로 팩토리얼 계산기를 만드는 방법을 배우게 됩니다. 이 랩은 for 루프의 구문 이해, 배열 요소 반복, 팩토리얼 계산 구현, 예외 처리, 팩토리얼 계산기 테스트 및 디버깅과 같은 필수 주제를 다룹니다. 이 랩을 마치면 이러한 기본적인 프로그래밍 개념에 대한 확실한 이해를 갖게 되며, 이를 활용하여 기능적인 팩토리얼 계산기를 구축할 수 있게 됩니다.

이 랩은 팩토리얼 계산기를 만드는 과정을 안내하기 위해 단계별 지침과 코드 예제를 제공합니다. 먼저, 배열을 반복하고 반복적인 작업을 수행하는 데 중요한 for 루프의 기본 구문을 배우게 됩니다. 그런 다음, 팩토리얼 계산에 필수적인 배열 요소에 접근하고 조작하는 방법을 탐구할 것입니다. 또한, 이 랩에서는 팩토리얼 계산 구현, 예외 처리, 최종 프로그램 테스트 및 디버깅을 다룹니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 초급 레벨의 실험이며 완료율은 100%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

For 루프 구문 이해하기

이 단계에서는 C 프로그래밍에서 배열을 반복하고 팩토리얼 계산과 같은 반복적인 작업을 수행하는 데 필수적인 for 루프의 기본적인 구문에 대해 배우게 됩니다.

기본적인 for 루프 구문을 보여주는 간단한 C 프로그램을 만들어 시작해 보겠습니다. WebIDE 를 열고 ~/project 디렉토리에 loop_example.c라는 새 파일을 만듭니다.

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

예시 출력:

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

for 루프 구문을 자세히 살펴보겠습니다.

  • int i = 0: 초기화 (Initialization) - 루프 카운터 변수를 초기 값으로 설정합니다.
  • i < 5: 조건 (Condition) - 이 조건이 참인 동안 루프를 계속합니다.
  • i++: 증가 (Increment) - 각 반복 후 루프 카운터를 증가시킵니다.

이제 프로그램을 컴파일하고 실행하여 루프가 어떻게 작동하는지 확인합니다.

gcc loop_example.c -o loop_example
./loop_example

for 루프는 반복 프로세스를 정확하게 제어할 수 있기 때문에 강력합니다. 배열을 순회하거나 계산을 수행하는 등 다양한 프로그래밍 요구 사항에 맞게 초기화, 조건 및 증가/감소 부분을 수정할 수 있습니다.

배열 요소 순회하기

이 단계에서는 C 에서 배열 요소를 반복하는 방법을 배우게 됩니다. 이는 팩토리얼 계산기를 구현하는 데 매우 중요합니다. 이전 단계의 for 루프 지식을 바탕으로, 배열 요소에 접근하고 조작하는 방법을 살펴보겠습니다.

배열 반복을 보여주기 위해 ~/project 디렉토리에 array_iteration.c라는 새 파일을 만들어 보겠습니다.

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

예시 출력:

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

주요 개념을 자세히 살펴보겠습니다.

  • int numbers[5]는 5 개의 정수 요소를 저장할 수 있는 배열을 생성합니다.
  • {10, 20, 30, 40, 50}은 특정 값으로 배열을 초기화합니다.
  • numbers[i]는 인덱스를 사용하여 개별 배열 요소에 접근합니다.
  • for 루프는 i를 인덱스로 사용하여 각 요소에 순차적으로 접근합니다.

이제 프로그램을 컴파일하고 실행합니다.

gcc array_iteration.c -o array_iteration
./array_iteration

반복을 더 실용적으로 만들기 위해 배열 요소의 합을 계산하는 예제를 만들어 보겠습니다.

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

예시 출력:

Sum of array elements: 150

이것은 for 루프를 사용하여 배열 요소에 대한 연산을 수행하는 방법을 보여줍니다. 이는 곧 구현할 팩토리얼 계산기에서 매우 중요할 것입니다.

팩토리얼 계산 구현하기

이 단계에서는 이전 단계에서 배운 루프 반복 기술을 사용하여 C 에서 팩토리얼 계산 함수를 구현하는 방법을 배우게 됩니다. 팩토리얼은 숫자를 그보다 작은 모든 양의 정수로 곱하는 수학적 연산입니다.

~/project 디렉토리에 factorial_calculator.c라는 새 파일을 만들어 보겠습니다.

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

예시 출력:

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

팩토리얼 계산을 자세히 살펴보겠습니다.

  • 0 과 1 의 팩토리얼은 1 입니다.
  • n 의 팩토리얼 (n!) = 1 2 3 ... n
  • calculateFactorial() 함수는 for 루프를 사용하여 숫자를 곱합니다.
  • 팩토리얼을 1 부터 시작하여 n 까지의 각 숫자로 곱합니다.

프로그램을 컴파일하고 실행합니다.

gcc factorial_calculator.c -o factorial_calculator
./factorial_calculator

계산기를 더 대화형으로 만들기 위해 사용자 입력을 받도록 프로그램을 수정해 보겠습니다.

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

예시 상호 작용:

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

예외 상황 처리

이 단계에서는 팩토리얼 계산기에서 음수와 정수 오버플로우를 일으킬 수 있는 큰 입력과 같은 엣지 케이스를 처리하는 방법을 배우게 됩니다. 안정적인 소프트웨어를 만들기 위해서는 강력한 오류 처리가 필수적입니다.

팩토리얼 계산기를 수정하여 이러한 엣지 케이스를 처리해 보겠습니다. ~/project 디렉토리에 factorial_edge_cases.c라는 새 파일을 만듭니다.

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

예시 출력:

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.

주요 오류 처리 기술:

  • 계산 전에 음수 확인
  • 정수 오버플로우를 방지하기 위해 INT_MAX 사용
  • 계산 오류를 나타내기 위해 -1 반환
  • 유익한 오류 메시지 제공

프로그램을 컴파일하고 실행합니다.

gcc factorial_edge_cases.c -o factorial_edge_cases
./factorial_edge_cases

더 사용자 친화적인 입력 처리를 위해 프로그램을 개선해 보겠습니다.

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

예시 상호 작용:

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.

팩토리얼 계산기 테스트 및 디버깅

이 마지막 단계에서는 다양한 테스트 기술과 디버깅 전략을 사용하여 팩토리얼 계산기를 철저하게 테스트하고 디버깅하는 방법을 배우게 됩니다.

다중 테스트 케이스와 디버깅 기능을 포함하는 포괄적인 테스트 프로그램을 만들어 보겠습니다. ~/project 디렉토리에 factorial_test.c라는 파일을 만듭니다.

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

프로그램을 컴파일하고 실행합니다.

gcc factorial_test.c -o factorial_test
./factorial_test

예시 출력은 다음과 같습니다.

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):

시연된 주요 디버깅 및 테스트 기술:

  • 함수 실행을 추적하기 위한 디버그 출력문
  • 엣지 케이스를 다루는 포괄적인 테스트 케이스
  • 잘못된 입력에 대한 오류 처리
  • 오버플로우 방지
  • 어설션 스타일 테스트
  • 대화형 테스트 모드

디버깅 팁:

  1. 로깅 및 함수 호출 추적에 printf() 사용
  2. 엣지 케이스를 명시적으로 처리
  3. 입력 유효성 검사 구현
  4. 더 큰 숫자 계산에 long long 사용
  5. 다양한 시나리오를 확인하기 위해 테스트 스위트 만들기

요약

이 랩에서는 C 프로그래밍에서 for 루프의 기본적인 구문을 배웠습니다. 이는 배열을 반복하고 팩토리얼 계산과 같은 반복적인 작업을 수행하는 데 필수적입니다. 또한 팩토리얼 계산기를 구현하는 데 중요한 배열 요소를 반복하는 방법도 살펴보았습니다.

기본적인 for 루프 구문을 보여주는 간단한 C 프로그램을 만들어 루프의 초기화, 조건 및 증가/감소 부분을 이해하는 것으로 시작했습니다. 그런 다음 for 루프를 사용하여 정수 배열을 반복하고 배열 요소에 액세스하고 조작하는 방법을 배웠습니다.