【问题标题】:Calculating Fibonacci Numbers Recursively in C在 C 中递归计算斐波那契数
【发布时间】:2010-01-31 02:12:50
【问题描述】:

我正在尝试通过编写一个简单的程序来输出斐波那契数字来学习 C。它不起作用。

fibonacci.h

unsigned int fibonacci_recursive(unsigned int n);

fibonacci.c

#include <stdio.h>
#include "fibonacci.h"

main() {
    unsigned int i;
    for (i = 0; i < 10; i++) {
        printf("%d\t%n", fibonacci_recursive(i));
    }
    getchar();
}

fibonacci_recursive.c

unsigned int fib_rec(unsigned int n);

main(unsigned int n) {
     return fib_rec(n);
}

unsigned int fib_rec(unsigned int n) {
    if (n == 0) {
        return 0;
     } 
     if (n == 1) {
           return 1;
     }
     return fib_rec(n - 1) + fib_rec(n - 2);
}

这是我尝试构建项目时 VS 2010 给我的错误消息:

1>ClCompile:
1>  fibonacci_recursive.c
1>fibonacci_recursive.obj : error LNK2005: _main already defined in fibonacci.obj
1>fibonacci.obj : error LNK2019: unresolved external symbol _fibonacci_recursive referenced in function _main
1>c:\users\odp\documents\visual studio 2010\Projects\Fibonacci\Debug\Fibonacci.exe : fatal error LNK1120: 1 unresolved externals
1>
1>Build FAILED.
1>

我在这里做错了什么?感谢您帮助 C 新手。

【问题讨论】:

标签: c fibonacci


【解决方案1】:

你的方法看起来很奇怪,你应该有:

  • 带有 main 方法的主文件(例如 main.c),其中包括 fibonacci.h
  • 带有原型unsigned int fibonacci_recursive(unsigned int n);fibonacci.h
  • 带有方法实现的fibonacci.c,也应该包含fibonacci.h

其实你也定义了两次main函数..

ma​​in.c

#include <stdio.h>
#include "fibonacci.h"

main()
{
    unsigned int i;
    for (i = 0; i < 10; i++)
    {
        printf("%d\t%n", fibonacci_recursive(i));
    }
    getchar();
}

fibonacci.h

unsigned int fibonacci_recursive(unsigned int n);

fibonacci.c

#include "fibonacci.h"
unsigned int fibonacci_recursive(unsigned int n)
{
    if (n == 0) 
    {
        return 0;
     } 
     if (n == 1) {
           return 1;
     }
     return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2);
}

【讨论】:

  • 忘了修正一个错字,它是 fib_rec.. 我不知道你以前用什么方式来命名同一个函数:D
  • 另一个用户删除了一个帖子,其中他指出您在 printf 字符串中使用 %n 的事实。用 \n 改变它
【解决方案2】:

您在项目中定义了两次main() 函数。这是您的程序的入口点,您只需要一个。

【讨论】:

    【解决方案3】:

    您的 printf 需要 \n 而不是 %n。此外,您可以简化为:

    #include "fibonacci.h"
    
    unsigned int fibonacci_recursive(unsigned int n) {
    if (n < 2) 
        return n;
    else
        return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2);
    }
    

    【讨论】:

    • 显然你不能简化它,因为它会返回 0 1 2 3 5 8 13 .... 如果你使用 if(n == 0) return 0;如果(n == 1)返回1;你会得到正确的 0 1 1 2 3 5 8 13
    • @mikkeljuhl:感谢您的评论。这是一个错字:(n &lt;= 2) 应该是 (n &lt; 2)。我现在已经修复并测试了它。您不需要三向条件。
    • 好,所以我们现在在同一页面上:-)
    【解决方案4】:

    您尚未创建在 fibonacci.h 中声明的 fibonacci_recursive 函数。

    【讨论】:

      【解决方案5】:

      你声明了两个main()函数,换行符是'\n'

      【讨论】:

        【解决方案6】:

        好吧,我先说递归函数不是计算斐波那契的有效方法,它可能仅用于开发培训/演示目的,因为每个递归都存储在堆栈中,而且对于较大的斐波那契数,它也可能溢出。 编写一个使用循环的更高效的斐波那契函数是相当值得的,如下代码:

        #include <stdio.h>
        
        #define MAX_ITERS 20
        
        
        int fibonacci(int);
        
        int main(int argc, char *argv[])
        {
            unsigned int iters;
        
            if(argc>1) {
                iters=atoi(argv[1]);
            } else
                iters=MAX_ITERS;
        
            fibonacci(iters);
        
            return 0;
        }
        
        int fibonacci(int iterations)
        {
           unsigned register int i;
           double first=0.0, second = 1.0, lastsum;
           printf("First %d iterations of Fibonacci series are :\n",iterations);
        
           for ( i = 0 ; i < iterations ; i++ )
           {
              if ( i <= 1 )
                 lastsum = (double)i;
              else
              {
                 lastsum = first + second;
                 first = second;
                 second = lastsum;
              }
              printf("%.0f\n",lastsum);
           }
        
        }
        

        尝试自行比较,运行 ./fibonacci 50 与此方法,例如在低成本处理器上(例如,在 Raspberry PI 上)和带有 的处理器递归函数 和 50 个第一个数字,看看区别! ,-)

        【讨论】:

        • 避免使用register,尤其是在unsignedint 之间:虽然这不是一个错误,但对于新手读者来说,它是非常无用且教学价值低的。 fibonacci() 定义为返回 int 但没有 return 语句。 MAX_ITERS 应命名为 DEFAULT_ITERS。为什么将itersi 定义为unsigned?如果您确实将负值作为命令行参数传递给main,那么您最终会迭代很长时间。您还忘记将&lt;stdlib.h&gt; 包含在atoi() 中。您绝对应该打开警告以避免所有这些错误。
        • 当然,chqrlie,因为缺少 atoi 的包含,我很抱歉我错过了它。但是调用 MAX_ITERS 或 DEFAULT_ITERS 只是一个“命名”问题。我的意思是,我可以同意你让代码易于阅读,但请避免如此严厉.. :-) Iters 是无符号的,因为我认为传递负数只是为了指定迭代次数是无稽之谈.问候。
        猜你喜欢
        • 1970-01-01
        • 2010-12-03
        • 2012-12-03
        • 2011-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-02
        相关资源
        最近更新 更多