【发布时间】:2015-04-25 16:08:04
【问题描述】:
对于递归和迭代版本,我有以下斐波那契代码:
#include <stdio.h>
typedef long long INT;
long long recursive (long long i) {
if (i == 0) return 0;
if (i == 1) return 1;
return recursive (i-1) + recursive (i-2);
}
long long iterative (long long i) {
INT counter = i-1;
INT fib1 = 0;
INT fib2 = 0;
// first iteration
fib1 = 0;
fib2 = 1;
while (counter > 0) {
INT temp1 = fib1;
INT temp2 = fib2;
fib1 = fib2;
fib2 = temp1 + temp2;
counter--;
}
}
int main (int argc, char **argv) {
printf("Result: %lli\n", iterative(10));
return 0;
}
我尝试使用 GCC -O2 优化对其进行编译,以查看递归是否会比迭代执行得更好,但我注意到一个有趣的现象:使用 -O2 编译时,迭代函数输出 0 而如果编译时不带标志,它输出正确的数字。
gcc -O2 fibonacci.c -o fib && ./fib:
Result: 0
gcc fibonacci.c -o fib && ./fib:
Result: 55
【问题讨论】:
-
你不会在迭代中返回结果。
-
... 这给了你未定义的行为。打开这些警告!
-Wall -Wextra -Werror -pedantic -std=c99(或其他标准版本) -
是的,就是这样。那么为什么我在没有优化的情况下编译它会起作用呢?
-
这就是未定义行为的作用。任何事情都有可能发生。当函数实际上没有返回任何东西时,包括一个给出你期望的结果的函数。
-
而且你没有对递归和迭代进行公平的比较。当结果为 n 时,递归斐波那契实现使 n 次递归调用递归 (1)。
标签: c gcc optimization