用于计算阶乘的C程序

时间:2016-03-25 08:56:27

标签: c math recursion

我写了一个小函数,用于计算C中数字的阶乘 如下:

int factNnumbers(int n)
{
    if(n == 1)
        return 1;
    else
        return (n*factNnumbers(--n));
}

我将上面显示的函数称为:

factNnumbers(takeInputN());

其中输入函数(takeInputN)定义为:

int takeInputN()
{   
    int n;
    printf("\n\nHow many numbers ?? \n ");
    scanf("%d", &n);
    return n;
}

如果我在我的析因代码中更改了一行,如下所示,我的程序运行正常。否则使用上面的代码,它会打印输入数字-1的阶乘(例如,如果数字输入为5,则会打印4的阶乘。为什么会这样?

int factNnumbers(int n)
{
    if(n != 1)
        return (n * factNnumbers(--n));
}

6 个答案:

答案 0 :(得分:6)

您正在调用未定义的行为,它在一个版本中运行只是一个意外:

return (n*factNnumbers(--n));

你首先使用n然后减少它还是反过来?我不知道,编译器也不知道,它可以自由地执行其中任何一个或格式化您的硬盘驱动器。只需使用n * f(n - 1)

另外,你的工作"版本不会返回n==1案例,这是非法的。

答案 1 :(得分:6)

问题是你在同一个表达式中阅读和修改n

n * factNumbers(--n)

n*子表达式的--n参数的评估未被排序,这为您的代码提供了未定义的行为。

最简单的解决方案(以及IMO,更具表现力),就是说n - 1你的意思:

n * factNumbers(n - 1)

问题底部的“改进”代码实际上更加错误。在那里,你有一个控制路径,它将返回一个未指定的值: clear no-no。

注意:这个答案是在问题仍然具有C ++标记时编写的,并使用C ++术语。 C中的最终效果是相同的,但术语可能不同。

答案 2 :(得分:2)

代码中有两种未定义行为的原因:

  1. 首先评估n中的--nn * factNnumbers(--n)是否未指定。
    请参阅this。你只想n * factNnumbers(n - 1),为什么减少?之后你没有使用递减的n(至少你不想这样做)。

  2. 您没有在所有控制路径上返回值,n == 1会返回什么?一个不确定的值会弄乱整个结果。

答案 3 :(得分:0)

减法规则: X = Y--首先将I的值传递给X,然后递减 X = --I首先通过并递减递减值X

对于您的情况,您将作为参数传递的参数值递减到函数factNnumbers。因此纠正这个错误,我邀请你把(n-1)代替(--n)。

答案 4 :(得分:0)

我认为最好将math.h中的tgamma函数用于涉及因子(例如泊松分布等)的双精度计算:tgamma(n + 1)将为您提供factorial(n)。

辅助函数的增长非常快,对于太大而无法容纳整数类型的值,这也将起作用。

答案 5 :(得分:-1)

当n <= 1(或代码中= = 1)时,阶乘函数必须返回1.此外,您的代码中的--n为false,并且应为n-1:

function factorial(n)
{
   if (n<=1)
      return 1;
   else
      return n * factorial(n-1);
}