在C语言中,常见的数据类型有short,int等数据类型,在进行较小数的存储和表示时是没有问题的,但是当我们想要进行大数的存储和表示时,就会出现数据溢出的问题,以求阶乘为例,使用int型数据的话,到13的阶乘数据就会溢出了,得到的结果为1932053504(使用Codeblocks),很明显是不对的。
那么如何解决这个问题呢?这里我们考虑使用的一个关键工具就是数组,基本思想是将阶乘过程中每次得到的数各位上的数分配到数组的各个元素中,如果出现了数组中某个元素在阶乘过程中得到了大于等于10的数,则求其进位,放到前一位(由于采用逆序输出,也就是数组元素的后一位),本位元素更新为本位元素的个位与前一位数组元素的的进位,在这个过程中有一个最高位的问题需要解决,也就是输出的起点,最高位默认为0(数组下标从0开始历遍),当最高位的的数组元素也得到了大于等于10的数,还需要进行最高位+1的操作。
其实看完基本思想以后,相信很多朋友已经大致理解了这个程序,但是在实操中如何用代码来编写或许还存在问题,我写的具体代码如下,供大家参考:
#include<stdio.h>
int main(){
int arr[50]={
1}; //数组的大小可以根据需要设置,这里我按照50来编写的,数组第一位(arr[0])设置为1,其余为0//
int high=0; //设置最高位//
int i; //历遍数组的下标//
int j=1; //阶乘起点//
int n; //阶乘终点//
int temp[50]; //进位的数组//
int flag;
scanf("%d",&n);
while(j<=n){
for(i=0;i<=high;i++){
arr[i]=arr[i]*j; //数组每一位元素与n之前的数相乘//
temp[i]=arr[i]/10; //求每一个数组元素的进位置于temp数组中//
if(i==0) arr[i]=arr[i]%10; //数组元素求本位,本位为本位元素的个位与前一位元素的进位之和//
else arr[i]=arr[i]%10+temp[i-1];
if(i==high&&temp[i]>0){
//当数组最高位的元素有进位时最高位改变//
high=high+1;
arr[high]=temp[i]; //最高位元素的更新//
break;
}
else ;
}
j++;
}
//下面的循环将进位后得到的数组元素中所有能继续进位的元素继续进位,进位不彻底是一个很容易犯的错误!!//
do{
flag=0; //每次循环执行时先设置flag变量为0//
for(i=0;i<50;i++){
//先将temp数组中元素全部置为0,防止进位后的temp数组不能覆盖掉原来temp数组非0的元素,从而进入死循环//
temp[i]=0;
}
for(i=0;i<=high;i++){
//与上同//
temp[i]=arr[i]/10;
arr[i]=arr[i]%10+temp[i-1];
if(i==high&&temp[i]>0){
high=high+1;
arr[high]=temp[i];
break;
}
}
for(i=0;i<50;i++){
//如果进位后的temp数组中还有非0的元素说明进位不彻底,flag赋值为1,继续进位//
if(temp[i]) flag=1;
}
}while(flag);
printf("%d的阶乘:",n);
for(i=high;i>=0;i--){
//从最高位开始逆序输出//
printf("%d ",arr[i]);
}
printf("\n");
}
代码我调试过了,应该是没有问题的,建议大家再调试的时候多测几组数据,因为可能你所测试的数据刚好避免了你程序中的bug。
希望这篇文章能对大家有所帮助,同时代码中如果存在问题或者能够简化的地方欢迎大家批评指正。
最后,愿与诸君共勉,在学习编程的道路上一起前行!