首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言計算階乘n!:循環實現與邊界處理

     編輯:C 語言問答

問題描述

輸入非負整數n,計算n! (階乘)。0! = 1,負數報錯。

標準循環實現

#include 

int main() {
    int n;
    printf("請輸入非負整數: ");
    scanf("%d", &n);
    
    if (n < 0) {
        printf("錯誤:輸入必須為非負整數!\n");
        return 1;
    }
    
    unsigned long long result = 1;  // 使用64位無符號擴大範圍
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    
    printf("%d! = %llu\n", n, result);
    return 0;
}

數據類型選擇與溢出分析

類型最大值最大可計算階乘
int (32位)2,147,483,64712! = 479,001,600
long long (64位)9,223,372,036,854,775,80720! ≈ 2.43×10¹⁸
unsigned long long18,446,744,073,709,551,61520! (同上)
double≈1.8×10³⁰⁸170! (精度損失)

進階實現:大數階乘 (突破類型限制)

使用數組模擬大整數,每位存儲一位十進制數字:

#include 
#include 

#define MAX_DIGITS 10000  // 支持 ~35000!

void multiply(int *digits, int *len, int multiplier) {
    int carry = 0;
    for (int i = 0; i < *len; i++) {
        int product = digits[i] * multiplier + carry;
        digits[i] = product % 10;
        carry = product / 10;
    }
    while (carry > 0) {
        digits[(*len)++] = carry % 10;
        carry /= 10;
    }
}

void factorial_big(int n) {
    int digits[MAX_DIGITS] = {1};
    int len = 1;
    
    for (int i = 2; i <= n; i++) {
        multiply(digits, &len, i);
    }
    
    // 高位在前輸出
    for (int i = len - 1; i >= 0; i--) {
        putchar('0' + digits[i]);
    }
    putchar('\n');
}

int main() {
    int n;
    scanf("%d", &n);
    if (n < 0) return 1;
    factorial_big(n);
    return 0;
}

遞歸實現 (教學用,不推薦生產)

unsigned long long factorial_rec(int n) {
    if (n <= 1) return 1;
    return n * factorial_rec(n - 1);
}
// 缺點:棧溢出風險,重複計算,無尾遞歸優化

優化技巧

  1. 查表法:預計算0!~20!存入數組,O(1)查詢
  2. 斯特靈公式:近似計算大數階乘 n! ≈ √(2πn)(n/e)ⁿ
  3. 質因子分解:n!的質因子分解求組合數時避免大數運算

完整健壯版本

#include 
#include 

int main() {
    int n;
    printf("輸入 n (0-20): ");
    if (scanf("%d", &n) != 1 || n < 0 || n > 20) {
        printf("輸入無效!請輸入 0 到 20 之間的整數。\n");
        return 1;
    }
    
    unsigned long long fact = 1;
    for (int i = 2; i <= n; i++) {
        fact *= i;
    }
    
    printf("%d! = %llu\n", n, fact);
    return 0;
}

階乘計算看似簡單,實則涉及數據類型範圍、邊界檢查、溢出處理、大數算法等核心計算機科學概念。初學者掌握循環實現即可,進階者可挑戰大數階乘實現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved