我是 C 语言新手,正在尝试使用它。所以我最终实现了斐波那契代码(迭代和递归)。我编写了一个测试函数,它应该给我一个绿色(我的实现有效)或红色。它说我得到了正确的返回值,但它的状态是红色的。这两个值都应该是 unsigned long。我正在 OSX 上使用 make 进行编译
#include <stdio.h>
unsigned long fibonacci(unsigned long n);
void test_fibonacci(unsigned long n, unsigned long assertion);
int main(int argc, char* argv[])
{
test_fibonacci(1, 1);
test_fibonacci(2, 1);
test_fibonacci(3, 2);
test_fibonacci(10, 55);
return 0;
}
unsigned long fibonacci(unsigned long n)
{
unsigned long result = 1;
unsigned long lastResult;
for (unsigned long i = 2; i <= n; i++)
{
// save the current result to save it as the lastResult after this iteration
unsigned long lastResultTmp = result;
result = lastResult + result;
lastResult = lastResultTmp;
}
return result;
}
void test_fibonacci(unsigned long n, unsigned long assertion)
{
printf(
"fibonacci(%lu): %lu | %s | asserted: %lu\n",
n,
fibonacci(n),
(fibonacci(n) == assertion) ? "green" : "red",
assertion
);
}
我的生成文件
CFLAGS=-Wall -g
all: main
clean:
rm -f main
rm -Rf *.dSYM
输出:
fibonacci(1): 1 | green | asserted: 1
fibonacci(2): 1 | red | asserted: 1
fibonacci(3): 2 | red | asserted: 2
fibonacci(10): 55 | red | asserted: 55
最佳答案
我没有得到你的输出。这是我所看到的:
fibonacci(1): 1 | green | asserted: 1
fibonacci(2): 2 | red | asserted: 1
fibonacci(3): 4 | red | asserted: 2
fibonacci(10): 3353 | red | asserted: 55
我很好奇为什么,所以我用 valgrind 运行它。很快就弹出了这个错误:
==5619== Conditional jump or move depends on uninitialised value(s)
==5619== at 0x4005E7: test_fibonacci (fibonacci.c:31)
==5619== by 0x400559: main (fibonacci.c:9)
所以看起来这与读取未初始化的变量有关,这会给你错误的值。这最终将我们指向这里:
unsigned long fibonacci(unsigned long n)
{
unsigned long result = 1;
unsigned long lastResult; // <---- LOOK HERE
for (unsigned long i = 2; i <= n; i++)
{
// save the current result to save it as the lastResult after this iteration
unsigned long lastResultTmp = result;
result = lastResult + result;
lastResult = lastResultTmp;
}
return result;
}
请注意,lastResult
尚未初始化,但已在行中读取
result = lastResult + result;
所以看来您需要初始化该值。由于该值对应于之前的斐波那契数,因此您应该初始化为零。这样做会导致所有测试通过。
现在,究竟发生了什么导致您看起来得到了正确答案但仍然失败?请注意,您在测试代码中调用了两次斐波那契。我的猜测是,对 fibonacci
的第一次调用 - 被打印的那个 - 纯粹是随机的机会恰好工作正常,因为由于某种原因,第一个 lastResult
中的值调用恰好为 0。但是,我猜测对 fibonacci
的第二次调用(与预期结果进行比较的调用)没有返回相同的结果value 作为第一次调用,因为无论出于何种原因,在进行第二次调用时 lastResult
的值不为 0。这就是未定义行为的问题 - 可能会发生这样奇怪的事情!
关于在 C 中比较两个相等的 unsigned long 计算结果为 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37953949/