斐波那契程序错误

Error in Fibonacci program

我正在尝试使用 C 语言查找第 k 个斐波那契数:

int fibk(int k)
{
    if(k == 1 || k== 2)
        return 1;

    int i,a = 1,b = 1;

    for(i=3;i<=k;i++)
    {
            b = a + (a=b);
    }

    return b;
}

我之前使用过这段代码来交换两个变量值:

    a = a + b - (b = a)

所以我在尝试:

     b = a + (a=b);

但此代码首先将 a 的值更改为 b,然后简单地将其加回自身,有效地使其值加倍,而不是将其添加到其先前的值。

为什么交换代码有效,但查找下一个斐波那契数的代码无效?

'a' 上的操作可能未定义,因此 "swapping code" 实际上 "not working"。一种方法是,您可以使用 tem(临时)变量来保留 b 的值。像这样尝试:

tem = a + b;
a = b;
b = tem;

回答问题:a = a + b - (b = a);b = a + (a=b); 都有 未定义的行为 。 C 既不指定求值顺序,也不指定副作用(例如变量赋值)发生的顺序,除非有明确的序列点。因此,在上述两个表达式中,右侧的赋值可能发生在访问赋值变量的值之前、之后或期间。 ("while" 的情况涵盖了在多个机器指令中完成赋值的情况,可能是因为变量太大而无法在一条指令中存储或加载。)

"Undefined behaviour" 就是这样——未定义。它可能会模仿您错误期望的行为;它可能只是以意想不到的顺序做事;它可能会产生难以理解的垃圾;或者它可能会被编译器简单地删除,这样什么都不会发生。或许多其他可能性。并且不能保证具有未定义行为的程序的行为方式与明天编译的相同程序的行为方式相同。


作为小额奖励,因为您似乎试图避免使用临时变量,这里有一个不同的斐波那契 hack,没有临时变量也没有 UB:

int fibk(int n) {
  int a = 1, b = 0, i = n - 1;
  for (; i > 0; i -= 2) {
    b += a;
    a += b;
  }
  return i ? b : a;
}

由于它展开了循环,它可能会稍微快一些。再一次,它可能不会。 :)