C语言 未从递归函数中获得所需输出

bvuwiixz  于 2023-04-05  发布在  其他
关注(0)|答案(3)|浏览(114)

当我使用不同的方法来计算以下方法n=n*i的阶乘值,然后输出我得到负值

#include <stdio.h>

int
foo(int x)
{
    for (int i = 1; i < x; i++) {
        x = x * i;
        printf("%d ", x);
    }

    return 0;

}

int
main()
{
    int x = 4, m;

    m = foo(x);
    printf(m);
    return 0;
}

我得到的输出:

4 8 24 96 480 2880 20160 161280 1451520 14515200 159667200 1916006400 -861720576 
Process finished.

我想更新在相同的价值造成一些问题请帮助

yc0p9oo0

yc0p9oo01#

对于初学者来说,你的函数不是递归的。:)
在main中调用printf

printf(m);

不正确。函数printf的第一个参数的指针类型为const char * restrict
对于类型int,可以计算阶乘的最大有效数等于12

12! = 479001600

假设sizeof( int )等于4
最好使用函数unsigned long long int的返回类型。在这种情况下,可以计算阶乘的最大有效数等于20

20! = 2432902008176640000

同样,函数参数至少应该有无符号整数类型unsigned int。将参数声明为有符号整数类型没有意义。
并且函数的返回值0没有意义。函数应该返回计算的阶乘。
此外,您的函数错误地计算了有效值0的阶乘。0!等于1
可以通过以下方式声明和定义函数

unsigned long long int foo( unsigned int n )
{
    unsigned long long int factorial = 1llu;

    while ( n > 1 ) factorial *= n--;

    return factorial;
}

如果你想写一个递归函数,那么它可以看起来像下面这样

unsigned long long int foo( unsigned int n )
{
    return n < 2 ? 1llu : n * foo( n - 1 ); 
}

这是一个演示程序。

#include <stdio.h>

unsigned long long int foo( unsigned int n )
{
    return n < 2 ? 1llu : n * foo( n - 1 );
}

int main( void )
{
    const unsigned int MAX_FACTORIAL_VALUE = 20;

    for (unsigned int i = 0; i <= MAX_FACTORIAL_VALUE; i++)
    {
        printf( "%u! = %llu\n", i, foo( i ) );
    }
}

程序输出如下所示

0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000
16! = 20922789888000
17! = 355687428096000
18! = 6402373705728000
19! = 121645100408832000
20! = 2432902008176640000

如果你愿意,你可以使用上面显示的非递归函数来代替递归函数。
你也可以这样改变函数,它会向用户发出传递给函数的值太大的信号。

unsigned long long int foo( unsigned int n )
{
    const unsigned int MAX_VALID_VALUE = 20;

    if (MAX_VALID_VALUE < n) return -1;

    unsigned long long int factorial = 1llu;

    while (n > 1) factorial *= n--;

    return factorial;
}

也就是说,如果传递的值不在可接受的范围内,则函数返回值( unsigned long long int )-1
然后在main中你可以写

#include <limits.h>

//...

unsigned long long int m = foo( some_value );

if ( m == ULLONG_MAX ) puts( "Error: too big value." );
voj3qocg

voj3qocg2#

这里有几个问题。主要的一个是,你的for循环正在改变x,它用于指示何时停止循环。你需要使用不同的变量来跟踪你的结果。如果不是因为这个事实,你将有一个无限循环,而int最终会绕回并成为负循环。
你的循环使用i < x作为停止条件,但是你需要在等式中包含x,所以它应该是i <= x
此外,函数返回0,而不是阶乘的结果。
最后,您有:

printf(m);

这不是printf()的工作方式,你需要给予它一个格式字符串来告诉它如何打印参数,例如。

printf("%d\n", m);

把所有这些放在一起,你可能有:

int factorial(int x)
{
    int result = 1;
    for (int i = 2; i <= x; i++) {
        result *= i;
        printf("%d ", result);
    }

    return result;
}

int main()
{
    int x = 4, m;

    m = factorial(x);
    printf("%d\n", m);
    return 0;
}

给予:

2 6 24 24
pvcm50d1

pvcm50d13#

1.在递归实现中,您不在循环中迭代

  1. printf首先需要格式
unsigned long long fact(unsigned int x) // as fact of the negative number is not defined
{
    if(x) return x * fact(x - 1);
    return 1;
}

int main(void)
{
    unsigned long long m;
    unsigned int x = 5;

    m = fact(x);
    printf("%llu\n", m);
    return 0;
}

或者检查它是否溢出

unsigned long long fact(int x) // as fact of the negative number is not defined
{
    if(x) 
        if(x < 0 || x * (x - !x) < x ) return 0;
        else return x * fact(x - 1);
    return 1;
}

int main(void)
{
    unsigned long long m;
    int x = 120;

    m = fact(x);
    if(m) printf("%llu\n", m);
    else printf("Undefined\n");
    return 0;
}

相关问题