C中的一个程序,用于获得小于给定数字的前两个斐波纳契数

时间:2017-07-01 12:48:11

标签: c function fibonacci

#include <stdio.h>

int fibo(int);

int main() {
    int n, p[100];

    scanf("%d", &n);

    int i = 0;
    do {
        p[i] = fibo(i);
        i++;
    } while (p[i] <= n);

    printf("%d %d", p[i-1], p[i]);

    return 0;
}

int fibo(int i) {
    if (i == 0) {
        return 0;
    } else
    if (i == 1) {
        return 1;
    } else {
        return (fibo(i - 1) + fibo(i - 2));
    }
}

这是我写的程序。我得到了一个完全垃圾的答案。有人可以帮助我解决我的错误吗?

2 个答案:

答案 0 :(得分:2)

比较刚刚计算出的数组元素。该数组未初始化,行为未定义。

您可以通过以下方式修复代码:

int main() {
    int n, p[100];

    scanf("%d", &n);

    int i = 0;
    do {
        p[i] = fibo(i);
        i++;
    } while (p[i-1] <= n);

    printf("%d %d", p[i-2], p[i-1]);

    return 0;
}

但是,您的代码有几个小问题:

  • 您不会检查scanf()是否成功。
  • 将值存储到p数组时,不检查潜在的缓冲区溢出。
  • 对于n的小值,您有未定义的行为,因为您将在负偏移处读取p的条目。

以下是解决这些问题的更正版本:

#include <stdio.h>

int fibo(int);

int main(void) {
    int n, p[100];

    if (scanf("%d", &n) == 1) {
        for (int i = 0; i < 100; i++) {
            p[i] = fibo(i);
            if (p[i] > n)
                break;
        }
        if (i >= 2) {
            printf("%d %d\n", p[i - 2], p[i - 1]);
        }
    }
    return 0;
}

int fibo(int i) {
    if (i == 0) {
        return 0;
    } else
    if (i == 1) {
        return 1;
    } else {
        return (fibo(i - 1) + fibo(i - 2));
    }
}

但请注意,Fibonacci序列快速发散,并且可能发生算术溢出,从而导致未定义的行为,导致n的大值产生错误的结果。

这是一个更简单的解决方案,它不使用递归并且没有这个问题:

#include <stdio.h>

int main(void) {
    int n, a = 0, b = 1;

    if (scanf("%d", &n) == 1 && n > 1) {
        while (a < n - b) {
            int c = a + b;  /* no overflow possible */
            a = b;
            b = c;
        }
        printf("%d %d\n", a, b);
    }
    return 0;
}

答案 1 :(得分:0)

初始化i = -1,并在do while loop增量内首先

int i=-1;

do
{
    i++;
    p[i] = fibo(i);


  } while(p[i] <=n);


  printf("%d %d", p[i-1], p[i-2]);// print i-1 and i-2

问题是,当您使用原始问题的代码检查p[i]<=n时,您正在检查垃圾值,因为那时我已经增加了。