为什么我的CheckFactorial脚本不起作用?

时间:2018-10-28 00:32:26

标签: c math factorial

#include <stdio.h>

int checkiffactorial();
int factorial(int n);

int number;

int main()
{
    int answer, n, i;
    printf("Enter a number: ");
    scanf("%d", &number);
    answer = checkiffactorial();
    if (answer == 1)
    {
        printf("It's a factorial");
    }
    else
    {
        printf("It's not a factorial");
    }
}


int checkiffactorial()
{
    static int whichnumber = 1;
    int currnumber;
    if (whichnumber > number)
    {
        return 0;
    }
    if(whichnumber <= number)
    {
        currnumber = factorial(whichnumber);
        if (currnumber == factorial(number))
        {
            return 1;
        }
        whichnumber++;
        checkiffactorial();
    }
}

int factorial(int n)
{
    int i;
    int fac;
    for(i=1; i<=n; ++i)
    {
        fac = fac * i;
    }
}

为什么此代码不起作用? 我的C代码适合您输入数字并检查该数字是否可以作为阶乘。

例如:如果输入6,则应为是,因为3! = 6,但是如果您输入8,它将无法正常工作。

我不认为这是重复的,因为我做的方法不同。

请注意,我不太擅长C语言,因此任何额外的技巧都将不胜感激。

2 个答案:

答案 0 :(得分:0)

您需要纠正3个错误才能使该程序正常工作。

  1. 您正在将factorial的{​​{1}}与whichnumber的{​​{1}}进行比较。
factorial

您应将number中的 currnumber = factorial(whichnumber); if (currnumber == factorial(number)) //<----never be true { return 1; } factorial

whichnumber

2。您应该在number函数中初始化 currnumber = factorial(whichnumber); if (currnumber == number) //<----should check whether it's same with the number { return 1; } 变量,否则将产生一些垃圾值。

fac

3。计算factorial后,应返回int fac=1; //<-----initialize this variable 的值。

fact

这是修改后的代码:

factorial

答案 1 :(得分:0)

已向您指出,您不会从函数中返回值,而不会使用未初始化的值。这些错误很容易造成,但也很容易捕获:为编译器启用警告,它们会告诉您这些情况。

Suvojit的答案告诉您阶乘函数出了什么问题。不幸的是,您的阶乘检查出现了更多错误:

  • 您输入要检查的数字作为全局变量。这实际上应该是该函数的参数,以便您可以像调用is_factorial(n)那样调用它。
  • 您将计数器设为static变量。这就像一个全局变量,但是有一个限制,即只能在此函数中知道,这意味着您不能从外部进行更改。如果您的程序要检查几个数字,第二个调用将从您先前中断的地方开始,这会导致错误的结果。
  • 当然这是实现中想要的,因为您使用的是递归算法。在这种情况下,这不是一个好选择。使用循环。
  • 您的条件何时停止迭代(或何时中断循环)将数字与您阶乘的数字进行比较。您应该针对阶乘本身对此进行测试。

请注意,典型的int具有32位,并且可以表示正值,最高为2³¹。阶乘13!已经超过此限制。因此,您必须对照12个值检查您的数字。

您不需要阶乘函数,可以随便建立这些值,因为 n ! =( n − 1)! · n 。 (您可以使用阶乘函数,但是会一遍又一遍地进行相同的计算,这很浪费。对于这个玩具问题并不重要,但是值得记住这些事情。)

这是您的函数,完全重写了:

int is_factorial(int n)
{
    int fact = 1;
    int k = 1;

    while (k < 13 && fact <= n) {
        fact *= k;
        if (n == fact) return k;
        k++;
    }    

    return 0;
}

n不是阶乘时,它返回0,否则返回n是阶乘的数字。 (无论如何都使用此信息,所以为什么不提供它呢?调用者可以选择使用此信息还是将其用作真值。)

在此过程中,让我们调整main函数,以便程序检查错误的输入并打印出返回的额外信息:

int main(void)
{
    int n;

    printf("Enter a number: ");

    if (scanf("%d", &n) < 1) {
        printf("Illegal input!\n");
    } else {
        int m = is_factorial(n);

        if (m) {
            printf("%d is the factorial of %d!\n", n, m);
        } else {
            printf("%d is not a factorial!\n", n);
        }
    }

    return 0;
}

这里要带走的事情是,应该使用编译器警告来告诉您简单的错误,对于诸如此类的闭合问题,应避免使用全局变量和静态变量,并且循环通常比递归更简单。