C语言实现阶乘(附带源码)

一、项目背景详细介绍

阶乘(Factorial)是数学中最基础、最常见的运算之一,记作:

它广泛应用于:

  • 排列组合计算

  • 概率论

  • 数学级数

  • 数值分析

  • 算法竞赛

  • 递归函数教学

  • 栈帧结构教学

  • 大整数计算

由于阶乘随 n 增大增长极快,因此它也是数值计算中:

  • 溢出检测

  • 大整数存储

  • 算法效率比较

  • 递归/迭代的性能差异

的典型教学案例。

本项目将从基础到进阶,实现 C 语言版本的阶乘,包括:

  • 递归版本 factorial_recursive

  • 迭代版本 factorial_iterative

  • 大整数版本 factorial_bigint(数组表示法)

  • 错误检测

  • 输入合法性判断

  • 性能差异说明

同时,本项目完全按照你的博客格式要求,结构完整、详细、可直接用于课堂教学或技术博客输出。


二、项目需求详细介绍

本项目的需求主要包括:

(1)实现三种阶乘算法

  1. 递归法(Recursive)

  2. 迭代法(Iterative)

  3. 大整数方法(Big Integer Factorial)

(2)要求具备输入检查

  • n 必须为非负整数

  • n 过大会提示溢出风险(普通 int/long long 无法计算大数阶乘)

(3)输出格式友好

  • 普通阶乘输出普通整数

  • 大整数算法输出完整、高精度长整数

(4)要求代码结构清晰,函数分类明确

  • 各个算法独立为函数

  • 主函数可选择算法进行测试

(5)要求兼容 32 位与 64 位平台


三、相关技术详细介绍

实现阶乘涉及多个核心技术点,本章逐一讲解。


1. 递归调用(Recursion)

C 语言允许函数调用自身,这叫做递归

递归函数必须具备:

  • 终止条件(Base Case)

  • 递推关系(Recursive Case)

例如:

5! = 5 * 4! 4! = 4 * 3! ...... 1! = 1


2. 迭代(Iteration)

迭代是使用循环结构(for / while)不断累乘。

相比递归:

  • 不会消耗额外栈帧

  • 性能更好

  • 不会发生栈溢出


3. 大整数存储(Big Integer)

由于 20! 已经超出了 64 位整数的范围,因此要计算大整数阶乘,需要采用:

数组存储法

使用一个数组int digits[10000],每一位存储一个十进制数字。

例如 12345 存储为:

indexdigit
05
14
23
32
41

乘法时逐位处理并管理进位。

这是 C 语言中最常见的大整数算法。


4. 溢出检测(Overflow Detection)

普通整数类型范围:

类型大约最大阶乘
int(32位)12!
long long(64位)20!

我们会:

  • 当 n > 20 时禁止普通阶乘运算

  • 自动转为大整数算法


四、实现思路详细介绍

本章节讲解程序整体结构。


函数结构设计

  1. unsigned long long factorial_iterative(int n);
    实现普通迭代阶乘

  2. unsigned long long factorial_recursive(int n);
    实现递归阶乘

  3. void factorial_bigint(int n);
    输出大整数阶乘

  4. void multiply(int x, int digits[], int *size);
    大整数乘法

  5. int main();
    选择使用算法并测试


核心逻辑流程

  1. 输入 n

  2. 判断 n 的合法性

  3. 如果 n ≤ 20
    → 可以用递归或迭代算法

  4. 如果 n > 20
    → 必须使用大整数算法

  5. 输出结果


五、完整实现代码

/************************************************************ * C语言实现阶乘(Factorial) * 包含: * 1. 迭代版本 * 2. 递归版本 * 3. 大整数版本(数组高精度) * 4. 输入检查与测试 ************************************************************/ #include <stdio.h> #include <stdlib.h> /************************************************************ * 迭代法阶乘(n <= 20 可安全计算) ************************************************************/ unsigned long long factorial_iterative(int n) { unsigned long long result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } /************************************************************ * 递归阶乘(n <= 20) ************************************************************/ unsigned long long factorial_recursive(int n) { if (n <= 1) return 1; return n * factorial_recursive(n - 1); } /************************************************************ * 高精度大数阶乘辅助:将当前大整数 digits[] 乘以 x ************************************************************/ void multiply(int x, int digits[], int *size) { int carry = 0; for (int i = 0; i < *size; i++) { int product = digits[i] * x + carry; digits[i] = product % 10; // 当前位 carry = product / 10; // 进位 } while (carry) { digits[*size] = carry % 10; carry /= 10; (*size)++; } } /************************************************************ * 大整数计算 n!(支持超大 n) ************************************************************/ void factorial_bigint(int n) { int digits[10000]; // 存储结果的数组 int size = 1; // 当前有效数字个数 digits[0] = 1; // 初始值 1! for (int i = 2; i <= n; i++) { multiply(i, digits, &size); } // 逆序输出(高位在后) printf("%d! = ", n); for (int i = size - 1; i >= 0; i--) { printf("%d", digits[i]); } printf("\n"); } /************************************************************ * 主函数 ************************************************************/ int main() { int n; printf("请输入一个非负整数 n:"); scanf("%d", &n); if (n < 0) { printf("错误:阶乘不定义负数!\n"); return 0; } if (n <= 20) { printf("[迭代法] %d! = %llu\n", n, factorial_iterative(n)); printf("[递归法] %d! = %llu\n", n, factorial_recursive(n)); } else { printf("n 超过 20,普通 long long 溢出,自动启用大整数算法。\n"); factorial_bigint(n); } return 0; }

六、代码详细解读


1. factorial_iterative

  • 使用 for 循环累乘

  • 时间复杂度 O(n)

  • n ≤ 20 时不会溢出

  • 最安全稳定的普通阶乘算法


2. factorial_recursive

  • 通过递归关系n * factorial(n-1)实现

  • 有清晰数学意义

  • 若 n 过大可能栈溢出


3. multiply

  • 这是高精度阶乘的核心

  • 将数组表示的大整数乘以一个普通整数 x

  • 支持无限进位处理

  • 时间复杂度 O(size)


4. factorial_bigint

  • 用 digits[] 数组存储阶乘

  • 每次循环乘以 i(2 到 n)

  • 最终逆序输出结果

  • 可支持上千位的大数阶乘


5. main

  • 输入判断

  • 自动选择普通算法或大整数算法

  • 提供友好提示


七、项目详细总结

本项目从零开始实现了完整、可靠、教学级的阶乘计算系统,包含:

  • 迭代的效率与稳定性

  • 递归的数学美感

  • 大整数阶乘的工程价值

通过本案例,读者能掌握:

  • C 函数设计

  • 递归思想

  • 数组模拟大整数

  • 溢出检测

  • 复杂算法的分解与组件化实现

该项目非常适合初学者与教学场景,也可作为数值分析课程的实验项目。


八、项目常见问题及解答

Q1:为什么普通 long long 只能计算到 20!?

因为 21! > 2^63,会导致溢出。


Q2:递归比迭代慢吗?

是的。
迭代不需要压栈与出栈,每次调用开销更小。


Q3:大整数阶乘可以计算多大?

取决于数组大小
本代码支持约 8000~9000 位数字。


Q4:大整数算法为什么要逆序存储?

因为计算方便(低位在前),输出时再反转即可。


九、扩展方向与性能优化

以下是本项目可扩展的方向:


1. 使用动态数组(malloc)存储大整数

支持几百万位的大数。


2. 使用 Karatsuba 乘法加速

将大整数乘法从 O(n²) 优化为 O(n^1.58)。


3. 使用多线程并行分段乘法

加速计算 10000! 或更大阶乘。


4. 输出格式化(每 3 位加逗号)

让输出更易读。


5. 实现阶乘缓存(Memoization)

避免重复计算。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1005229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里通义实验室发布Wan2.2开源视频模型:MoE架构革新引领AIGC创作新范式

阿里通义实验室发布Wan2.2开源视频模型&#xff1a;MoE架构革新引领AIGC创作新范式 【免费下载链接】Wan2.2-T2V-A14B-Diffusers 项目地址: https://ai.gitcode.com/hf_mirrors/Wan-AI/Wan2.2-T2V-A14B-Diffusers 阿里巴巴通义实验室近日正式推出新一代开源视频生成模型…

DPDK KNI 模块:高性能网络数据平面的内核交互桥梁

有了KNI模块&#xff0c;DPDK应用程序就可以实现&#xff1a;选择性处理&#xff1a; DPDK专注处理关注的高性能数据路径流量&#xff0c;把自己不想要的协议、控制平面流量或要内核处理的包转发给内核协议栈。直接用内核已有的网络功能&#xff0c;不用在用户空间重新实现这些…

职场中令领导同事反感的行为(不定期更新)

一、缺乏沟通。二、语气生硬。三、板着个脸。四、甩锅。五、总是麻烦别人。六、稀里糊涂。七、有错不改。八、情绪化。九、摸鱼。十、拖拉。

5个秘诀让你的Windows右键菜单秒响应:终极解决方案揭秘

5个秘诀让你的Windows右键菜单秒响应&#xff1a;终极解决方案揭秘 【免费下载链接】ContextMenuManager &#x1f5b1;️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager "每次右键都要等上好几秒&#xff0c;那…

算法综合训练:五类编程题深度解析与实践(收藏这一篇就够了)

算法综合训练&#xff1a;五类编程题深度解析与实践 引言 算法是计算机科学的核心&#xff0c;也是编程能力的重要体现。在实际编程和算法竞赛中&#xff0c;我们常常会遇到各种类型的题目&#xff0c;它们考察不同的算法思想和编程技巧。本文将通过五类共十四道编程题的详细解…

超级计算力量:一文看懂GPU并行计算CUDA

GPU&#xff08;Graphic Processing Unit&#xff09;&#xff1a;图形处理器&#xff0c;显卡的处理核心。电脑显示器上显示的图像&#xff0c;在显示在显示器上之前&#xff0c;要经过一系列处理&#xff0c;这个过程有个专有的名词叫“渲染"。以前的计算机上没有GPU&am…

喜马拉雅音频数据采集:API接口分析与加密音频链接解密实战

目录 引言 项目目标 效果展示 网站抓包分析过程 抓包分析:探索喜马拉雅API的多层结构 第一步:打开网络监控,观察数据流动 第二步:分析请求参数,理解数据交换规则 第三步:解密认证机制,掌握访问控制策略 第四步:理解音频链接加密机制,掌握解密流程 第五步:解…

百度网盘下载工具终极指南:快速突破限速的完整教程

百度网盘下载工具终极指南&#xff1a;快速突破限速的完整教程 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 百度网盘的下载限速问题一直困扰着众多用户&#xff0c;官方客户…

深入Ascend C(三):构建端到端自定义LayerNorm算子与性能调优实战

引言在前两篇文章中&#xff0c;我们分别探讨了 Ascend C 的基础语法与内存模型&#xff08;第一篇&#xff09;&#xff0c;以及如何实现高性能卷积算子&#xff08;第二篇&#xff09;。然而&#xff0c;随着 Transformer 架构的普及&#xff0c;Layer Normalization&#xf…

去哪儿网航班数据采集:API接口分析与加密参数解密实战

目录 引言 项目目标 效果展示 网站抓包分析过程 抓包分析:探索去哪儿网API的加密机制 第一步:打开网络监控,观察数据流动 第二步:分析请求参数,理解数据交换规则 第三步:解密认证机制,掌握访问控制策略 第四步:理解双重加密机制,掌握解密流程 第五步:解析响…

LeetCode热题100--215. 数组中的第K个最大元素--中等

题目 给定整数数组 nums 和整数 k&#xff0c;请返回数组中第 k 个最大的元素。 请注意&#xff0c;你需要找的是数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入: [3,2,1,5,6,4]…

2024年8月中文大模型战力榜:国产模型全面崛起改写全球竞争格局

一、行业背景与研究意义 【免费下载链接】DeepSeek-V2-Chat-0628 DeepSeek-V2-Chat-0628&#xff0c;开源创新之作&#xff0c;AI聊天机器人性能卓越&#xff0c;编码能力出众。在LMSYS Chatbot Arena榜单脱颖而出&#xff0c;多项任务表现领先。升级优化&#xff0c;体验更佳&…

jsonnet介绍和使用

文章目录Jsonnet介绍一、Jsonnet 的核心特点二、基本语法示例1. 变量与局部作用域2. 函数3. 条件表达式4. 对象继承与覆盖5. 数组与列表推导三、典型使用场景✅ 配置文件管理&#xff08;如 Kubernetes、Terraform&#xff09;✅ 生成结构化数据&#xff08;JSON/YAML&#xff…

Redis持久化机制详解:RDB和AOF对决,哪个更胜一筹?

RDB持久化机制 RDB持久化机制就像是在玩电脑游戏时&#xff0c;你不想从头重新开始&#xff0c;就想着在特定关卡或者达到一定分数时&#xff0c;把当前游戏存档下来&#xff0c;下次再玩的时候&#xff0c;直接加载存档就可以继续玩了。 首先&#xff0c;得告诉Redis要定期存…

考研408--组成原理--day7--指令扩展操作码寻址

&#xff08;以下内容全部来自上述课程&#xff09; 目录指令格式1. 指令的定义2. 指令的分类2.1 按地址码数目分类2.2 按指令长度分类2.3 按操作码长度分类2.4 按操作类型分类3. 小结扩展操作码指令寻址1. 提出问题2. 顺序寻址2.1 按字编址--定长2.2 按字节编址--定长2.3 按字…

C语言实现幂级数(附带源码)

一、项目背景详细介绍幂级数&#xff08;Power Series&#xff09;是数学分析中一种极为重要的函数表达方式&#xff0c;通过将函数展开为一系列以某点为中心的无限项多项式&#xff0c;可以用来近似计算、求导、积分、解析表达、数值计算等。大量经典函数&#xff0c;如指数函…

GCC完全指南:从编译基础到高级项目构建(超详细)

GCC完全指南&#xff1a;从编译基础到高级项目构建 引言&#xff1a;GCC在Linux开发中的核心地位 GCC&#xff08;GNU Compiler Collection&#xff09;作为Linux生态系统中最重要、最核心的编译器套件&#xff0c;自1987年由Richard Stallman创建以来&#xff0c;已经发展成为…

JavaScript 全局对象 `globalThis` 的多环境统一:各引擎在实现跨环境引用时的设计权衡

JavaScript 全局对象 globalThis 的多环境统一&#xff1a;各引擎在实现跨环境引用时的设计权衡各位同仁&#xff0c;各位对JavaScript技术充满热情的朋友们&#xff0c;大家好。今天我们齐聚一堂&#xff0c;共同探讨一个在现代JavaScript开发中日益重要的话题&#xff1a;glo…

C语言实现队列(附带源码)

一、项目背景详细介绍队列&#xff08;Queue&#xff09;是计算机科学中最基础、最重要的数据结构之一&#xff0c;属于线性结构。它采用 先进先出&#xff08;FIFO&#xff1a;First In First Out&#xff09; 的原则&#xff0c;广泛用于实际系统中&#xff0c;例如&#xff…

JavaScript 的参数对象 `arguments` 与 命名参数的同步行为:在非严格模式下的内存陷阱

各位同仁&#xff0c;各位对JavaScript深怀探索精神的开发者们&#xff0c;下午好。今天&#xff0c;我们将深入探讨JavaScript语言中一个既古老又充满争议的特性——arguments对象。具体来说&#xff0c;我们将聚焦于它与命名参数在非严格模式下的同步行为&#xff0c;以及这种…