2017-04-01 89 views
2

我在Python中有一点编程经验,为了好奇,我开始学习C语言,至少是非常基础的东西。在一个教程,我发现了一个示例函数用于计算阶乘,这是这样的:C教程中的这个阶乘函数是错误的吗?

int factorial(int x) 
{ 
    int i; 
    for(i=1; i < x; i++) 
    { 
     x *= i; 
    } 
    return x; 
} 

我也为了增加这些线看的输出:

#include <stdio.h> 

int main() 
{ 
    int val; 
    val = factorial(5); 
    printf("%d\n",val); 
    return 0; 
} 

然后我编译的代码与gcc factor.c -o factor.out,运行和... ooops,结果是-1899959296,显然有错误。

一个尝试几次后,使用printf()同时打印ix,我想通了,出了什么问题(我认为):自从for回路检查的情况,如果该计数器小于x,然后在每一步x变得越来越大,i总是小于x,所以循环继续进行,大概在x的值太大时停止(这应该与int有关,对于各种数据类型我还不是很熟悉)。

所以,“解决”的问题,我改写这样的功能:

int factorial(int x) 
{ 
    int counter = x; 
    int number = x; 
    int i; 
    for (i=1; i < counter; i++) 
    { 
     number *= i; 
    } 
    return number; 
} 

予编译程序,运行和打印的值是120,它是正确的。

我在C中搜索了一些有关阶乘函数的例子,并且发现了许多比我更好的解决方案,考虑到负数和格式如long等等,但是所有这些都以某种方式似乎依靠两个“主要”变量,就像我的解决方案。

所以,最后一个问题:是提出的例子错了,还是我错过了什么?这真让我困扰,因为如果这样一个简单的例子是明显错误的,我应该质疑其余的可信度。

+0

找一个C的书和阅读有关'INT_MAX'等 – Olaf

+4

'如果这样一个简单的例子是公然错误的,我应该质疑其余的可信度。“ - 是的,绝对。不是因为他们弄错了一件简单的事情,而是因为他们在发布之前没有测试过他们的东西。 – Siguza

+2

为什么downvote?这个问题是完整的,我没有理由认为它应该被视为脱离主题。 – alk

回答

8

是的的确的。原始因子函数与您确定的原因完全错误。您不能使用x作为累加器和循环限制。

在您的版本中,我建议的一个改进是摆脱counter。由于您不再修改x,因此您无需保存副本。

int factorial(int x) 
{ 
    int number = x; 
    int i; 
    for (i=1; i < x; i++) 
    { 
     number *= i; 
    } 
    return number; 
} 

如果您反转循环,则可以在不使用其他变量的情况下执行此操作。

int factorial(int x) 
{ 
    int i; 
    for (i = x - 1; i > 1; i--) 
    { 
     x *= i; 
    } 
    return x; 
} 

虽然我不会这样写。修改输入参数的风格很差。

2

我认为通过放置循环条件i<=x并使用另一个变量来存储阶乘会纠正它。

这里是例子:

int factorial(int x) 
{ 
    int i; 
    int fact = 1; //store factorial 
    for (i = 1; i <= x; i++) 
    { 
     fact *= i; 
    } 
    return fact; 
} 

或者你可以使用递归函数

int factorial(int x) { 
    if (x == 1) 
     return 1; 
    else 
     return x * factorial(x - 1); 
} 
+0

是的,这些都是可能的有效解决方案。但是,这一点仍然有效:给出的例子是错误的! –

+0

你给出的例子是什么意思?在你的问题? –

+0

是的,教程提供的第一个功能 –