4

I'm trying to learn C by writing a simple program to output Fibonacci numbers. It isn't working.

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);
}

This is the error message VS 2010 gives me when I try to build the project:

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>

What am I doing wrong here? Thanks for helping someone new to C.

Nick Heiner
  • 119,074
  • 188
  • 476
  • 699
  • 1
    I think you are confused about the purpose of main(), that's not the main function of the file, but of the entire program. The name of the file is irrelevant in c. – caskey Jan 31 '10 at 03:06
  • possible duplicate of [Two files containing definition of main() Visual Studio?](http://stackoverflow.com/questions/646559/two-files-containing-definition-of-main-visual-studio) – outis Jul 20 '12 at 09:51

6 Answers6

11

Your approach seems strange, you should have:

  • a main file (example main.c) with the main method and that includes fibonacci.h
  • a fibonacci.h with the prototype unsigned int fibonacci_recursive(unsigned int n);
  • a fibonacci.c with the implementation of the method, and it should include fibonacci.h too

Actually you define main function twice too..

main.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);
}
Jack
  • 131,802
  • 30
  • 241
  • 343
  • forgot to fix a typo, it was fib_rec.. I don't know way you used to way to name the same function :D – Jack Jan 31 '10 at 02:27
  • 1
    Another used deleted a post in which he pointed the fact that you are using **%n** inside the printf string. Change it with **\n** – Jack Jan 31 '10 at 02:28
4

You have the main() function defined twice in your project. This is the entry point of your program, and you only need one.

andri
  • 11,171
  • 2
  • 38
  • 49
4

You need \n not %n for your printf. Also, you can simplify as:

#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);
}
Ramashalanka
  • 8,564
  • 1
  • 35
  • 46
  • Obviously you can't simplify it as that as that will return 0 1 2 3 5 8 13 .... where as if you use if(n == 0) return 0; if(n == 1) return 1; you will get the correct 0 1 1 2 3 5 8 13 – mikkeljuhl Jan 04 '13 at 15:48
  • @mikkeljuhl: Thanks for the comment. It was a typo: `(n <= 2)` should've been `(n < 2)`. I've fixed it now and tested it. You don't need the three way condition. – Ramashalanka Jan 05 '13 at 08:22
  • Good, so we are on the same page now :-) – mikkeljuhl Jan 06 '13 at 20:53
2

You haven't created a fibonacci_recursive function that you declared in fibonacci.h.

Tor Valamo
  • 33,261
  • 11
  • 73
  • 81
0

You declared two main() functions, and the new line character is '\n'.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
0

Well, I preface that recursive function is not an efficient method to calculate Fibonacci and it may be used for dev training/demonstrations purposes only, because every recursion is stored in stack, and it may also overflow for large fibonacci numbers. It is rather worth the effort to write down a more efficient Fibonacci function that uses a loop, like following code:

#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);
   }

}

Try to compare by your own, running ./fibonacci 50 with this method, for instance on a low cost processor (eg. on a Raspberry PI), and the one with the recursive functions and 50 first numbers as well, and see the difference! ,-)

gabolander
  • 11
  • 2
  • 4
  • Avoid using `register`, especially between `unsigned` and `int`: although it is not an error, it is quite useless and of poor pedagogical value for newbie readers. `fibonacci()` is defined as returning `int` but does not have a `return` statement. `MAX_ITERS` should be named `DEFAULT_ITERS`. Why do you define `iters` and `i` as `unsigned`? if you indeed pass a negative value as a command line argument to `main`, you end up iterating for a very long time. You also forget to include `` for `atoi()`. You should definitely turn warnings on to avoid all these mistakes. – chqrlie Aug 20 '16 at 14:20
  • Just sure, chqrlie, for missing include for atoi, I apologize I missed it.. but calling MAX_ITERS or DEFAULT_ITERS is only a "naming" matter. I mean, I can agree with you for making code easy to be read, but please let's avoid to be so severe .. :-) Iters is unsigned because I think is a nonsense to pass a negative number just to specify a number of iterations. Regards. – gabolander Jan 05 '17 at 11:29