0

I came up with the following code to work out Fibonacci sequence. My main question is, why does it return the correct value? If I added a line telling it to return a result when a==1, I'd understand getting the correct return value, but as it is, I can't work it out. I'd also like to know if there are any advantages in using the normal recursive algorithm over this one?

int calculate(int a,int result,int old)
{

    if (a>0)
    {
        printf("%d ",result);
        return calculate (a-1,result+old,result);
    }

}

int main()
{
    int number,choice;
    printf("To start from 0 enter 0. To start from one enter any other number.\n");
    scanf("%d",&choice);
    printf ("Choose the number of times you wish to go for.\n");
    scanf("%d",&number);
    if (choice==0)
    {
        printf("Result= %d",calculate(number,0,1));
        return 0;
    }
    printf("Result= %d",calculate(number,1,0));

    return 0;

}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    Since `calculate` does not always return a value, your code is malformed. You should have `return 0;` or something to handle the case when `a` is zero or negative. – Jonathan Leffler Mar 21 '16 at 22:56
  • 2
    You mean, in the `a==0` case, where you forgot to have it return anything, how does it magically work? You didn't tell it what to return, so it returned something random (this is what's called *undefined behavior*), but by good luck (or, actually, bad luck) it happened to return what you wanted. Obviously you wouldn't want to depend on it, though. Good compilers will warn you about this. – Steve Summit Mar 21 '16 at 22:57
  • 1
    Wouldn't a decent compiler at least generate a warning about the calculate function - along the lines of not all code paths return a value? – Skizz Mar 21 '16 at 22:58
  • I assume it would be very bad practice to say 'it works, so leave it like that', and that it's better to add it explicitly? –  Mar 21 '16 at 22:58
  • @Skizz Yes. (From this we can conclude that Orangesandlemons was probably not using what we would consider a decent compiler.) – Steve Summit Mar 21 '16 at 22:59
  • @Orangesandlemons Yes, yes, 1000% yes. Code like this magically "works" for just as long as you're looking at it, and then it starts failing precisely when you ship it to a customer. – Steve Summit Mar 21 '16 at 23:00
  • @ steve, yes. Although to get the correct result I'd actually need to return a==1, so would adapt my code to 'if a==1' return result, else...' –  Mar 21 '16 at 23:01
  • Using codeblocks, so I assume the default would be GCC? –  Mar 21 '16 at 23:01
  • Actually, looking at the code, the printf's in main won't print the right result will they? The printf in calculate probably does though. – Skizz Mar 21 '16 at 23:06
  • Probably Code::Blocks uses GCC, but which version of GCC, and which compilation options (and which default version of the standard). GCC 4.x uses the very old C90 (C89) standard by default; GCC 5.x uses the C11 standard (and no version of GCC uses the C99 standard by default, AFAIK). You need to compile with `-Wall` and maybe `-Wextra` and preferably `-std=c11` or `-std=gnu11` if you're using a 4.x version of GCC. I add more warnings, and `-Werror` so warnings are treated as errors. – Jonathan Leffler Mar 21 '16 at 23:06
  • @ skizz, no; the printf in main prints the right result, at least when I compile with codeblocks. –  Mar 21 '16 at 23:07
  • Note that you should probably end the `printf()` format strings with `\n` so that each number is printed on its own line. Output will be buffered until a newline is printed or the buffer fills. – Jonathan Leffler Mar 21 '16 at 23:07
  • All recursive functions should have code to handle one or more base cases (which evaluate the result without further recursion), and one or more recursive cases where the final result is calculated in terms of a slightly different invocation of the recursive function for which the result is, presumably, easier to calculate. Your function does not handle the base case explicitly. You are unlucky that you're getting a useful answer from it. – Jonathan Leffler Mar 21 '16 at 23:11
  • @ Jonathan, good to know. To be honest, it's quite rudimentary- I'd also want to replace int with at least a double etc. etc. It was mainly thinking about the differences between this and the classic recursive algorithm that made me even bother to see what the return value was (the original version had an 'else return 0' and relied solely on the print in calculate();) –  Mar 21 '16 at 23:15
  • My guess that you need a `return 0;` is wrong — you need an 'or something' and I think the 'or something' that you need is `return old;`. You might consider allowing the user to enter the two starting numbers, so you can generate arbitrary Fibonacci sequences, rather than restricting them to 0 and 1. – Jonathan Leffler Mar 21 '16 at 23:19
  • @Jonathan- Thanks, your suggestion 'if a==0 return old' does save me a line of code if I want to keep printing out the sequence as well as having a return value. I did already have working code, using 'if a==1, return result' as the other case (and converting the current if to an else) (the return 0 was when I didn't need a return value.) –  Mar 21 '16 at 23:26
  • I'd just add a single line `return old;` after the close brace of your `if (a > 0) { … }` code — actually, that's what I did. That then handles obstreperous users entering -99 when you expect them to enter something sane like 12. Note that you should really check that the `scanf()` operations succeed: `if (scanf("%d", &number) != 1) { …report error and exit… }` or something similar. – Jonathan Leffler Mar 21 '16 at 23:27

1 Answers1

0

It is recommended for this case to receive a value and return one too. You could simplify the code as follows:

/*Recursive fibonacci function*/
#include <stdio.h>

long fibonacci(int);

int main()
{

    long result;
    int number;

    printf("Enter an interger: ");
    scanf("%d", &number);
    result = fibonacci(number);
    printf("Fibonacci(%d) = %ld\n", number, result);

    getchar();
    return 0;


}

//Recursive definition of function fibonacci
long fibonacci(int n)
{
   if( n == 0 || n == 1)
       return ((long) n);
   else
       return fibonacci(n - 1) + fibonacci(n - 2);
}

Recursive methods are great but it consumes a lot of memory and iterative option seems so inefficient to solve a fibonacci series.

based in "c/c++". Deitel & Deitel

sonOFAthena
  • 108
  • 1
  • 6