我正在尝试使用 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 = a + b - (b = a);
和 b = a + (a=b);
都有 未定义的行为。 C 既不指定求值的顺序,也不指定副作用(例如变量赋值)发生的顺序,除非有显式的序列点。因此,在上述两个表达式中,右侧的赋值可能发生在访问所分配变量的值之前、之后或同时。 (“while”情况涵盖了在多个机器指令中完成赋值的情况,可能是因为变量太大而无法在单个指令中存储或加载。)
“未定义的行为”就是——未定义。它可能会模仿您错误期望的行为;它可能只是以意想不到的顺序做事;可能会产生难以理解的垃圾;或者它可能被编译器简单地删除,这样什么也不会发生。或者许多其他的可能性。并且不能保证具有未定义行为的程序将与明天编译的同一程序具有相同的行为。
<小时/>为了获得一点好处,因为您似乎试图避免使用临时变量,所以这里有一个不同的斐波那契黑客,没有临时变量,也没有 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;
}
由于它展开循环,因此可能会稍微快一些。话又说回来,可能不会。 :)
关于c - 斐波那契数列中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30748347/