该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
下面是对上面代码的正规化结果:
注意: 源代码中几个变量符号,对应下面程序的变量分别是:
_ -> result
__ -> K
_1 -> Z
调用上程序,是调用自身 main , 这个,为了简单,我改成一个main函数,和 compute 函数。 compute 函数 就相当于上面的main函数递归调用。
下面亦可改为,main调用自身的。 自需把 main函数删掉,然后把所有的compute 改为main即可。
#include
#define BITS 500 /*不小于结果的位数*/
long R , a , y , result[ (BITS + 11 ) / 6 ]={1,1} , Z=1 ;
/* 参数用途:
result 数组是用来记录 结果的,结果是从低位记在result 前面,高位在后面,并且程序采用的是:
1000000为基。
注意: 记录结果的是从下标 1 开始的。 result[0] 是用来记录最后结果的长度(即运算结果的位数)。
y : 是用来标记用的。0 : 表示递归计算累乘,1 : 表示递归输出。
a : a 是 记录输入的数,即求程序求 a! 。
R : 是大数乘法过程中的中间变量,记录溢出数。
Z : 这里是用来记录,当前与result 的第几个 数相乘。
*/
int compute(int K){
if(( K - 1 ) == 0 ) //K 初始值为1, 这里只是开始执行一次,输入数据。
{
scanf("%ld",&a);
if(a
else
{
printf("a! =\n");
if(a
else compute(2); // 这里是 调用递归计算,从2 计算开始累乘。
}
}
else
{
if(y == 0 ) // y == 0 表示 递归计算,否则就是递归输出结果
{
if( Z <= result[0] || K
// 一个是: 当Z 没有与result所有的成完(其实是大数的模拟手算运算)。
// 二个是: 当 乘数 K 还没有累乘到 a 时,
{
if(Z > result[0] ) // 如果Z > result[0] ,说明K 已经和result里的所有数,累乘完毕。即 大数与k 乘法结束。
//当一个K 成完之后,便 成下一个数 K +1 , 并且 R 清零,Z = 1 (表示从result第一位开始乘),
{
K ++ ;
R = 0 ;
Z = 1;
}
R += result[Z] * K;
result[Z] = R%1000000l;
R/=1000000l;
if( Z == result[0] && R != 0 )
{
result[0]++ ;
}
Z++;
}
else // 这个else语句,只执行一次,就是结果算出来后。
{
K = result[0] + a; // 这里 K = result[0] + a; 是与 下面的 K > a 对应的,这里是可以随意改的。
y++; // 这里Y++, 只是作为标志位,表示下面的递归不执行if(y==0)里的语句,执行else 里面的输出结果语句。
printf("%ld", result[K-a]); // 输出最高位(为什么把最高为单独拿出来?可以自己想想(提示:否则的话,可能输出006这样的前面有0的结果)。
K--;
}
compute(K);
}
else {
if(K > a )
{
printf("%06ld",result[K-a]); // 这里便是输出结果了,因为程序计算 用的基是1000000,
// 所以,如果中间位数不足 6位的是要在前面补0的。
// 它这里原先用的是 K[result-a] , 运行效果一样,这里我是没见过这没做的(当初能够编译成功,就有些纳闷)。
compute(K-1);
}
}
}
return 0;
}
int main()
{
compute(1);
return 0 ;
}