为什么这个函数给我无限循环?

时间:2017-08-18 21:14:46

标签: c recursion

int bar(int val) {
    int x = 0;
    while(val > 0) {
        x= x + bar(val-1);
    }
    return val;
}

我将此功能称为bar(3)。它正在无限循环中。为什么呢?

4 个答案:

答案 0 :(得分:2)

您需要在循环中更新val

x= x + bar(--val);

答案 1 :(得分:0)

我想扩展这个简单的问题以了解更多信息。请不要投票并在其上添加更多内容。

我添加了一些printf()来显示创建的函数堆栈。

int y=0; 
int bar(int val) {
    int x = 0;
    printf("val-before: %d\n", val);
    while(val > 0) {
        x= x + bar(val-1);
        printf("val-inside: %d\n", val);
    }
    y++;

    printf("bar(): %d finished\n", y);

    return val;
}

称之为

bar(3);

来自结束的一些输出:

bar(): 7528 finished
val-inside: 1
val-before: 0
bar(): 7529 finished
val-inside: 1
val-before: 0
bar(): 7530 finished
val-inside: 1
val-before: 0
bar(): 7531 finished
val-inside: 1
val-before: 0
bar(): 7532 finished
val-inside: 1

此更改产生8个功能。

正如haccks所说,如果我们在x= x + bar(--val);内更改while 它打破无限函数调用

并产生此输出:

val-before: 3
val-before: 2
val-before: 1
val-before: 0
bar(): 1 finished
val-inside: 0
bar(): 2 finished
val-inside: 1
val-before: 0
bar(): 3 finished
val-inside: 0
bar(): 4 finished
val-inside: 2
val-before: 1
val-before: 0
bar(): 5 finished
val-inside: 0
bar(): 6 finished
val-inside: 1
val-before: 0
bar(): 7 finished
val-inside: 0
bar(): 8 finished

答案 2 :(得分:0)

在编码时,您确实有多个无限循环,每个递归调用一个val > 0因为val未在循环中更新。当然,唯一真正运行的是最后一个,对于val = 1,它一直调用bar(0),返回0,因此x甚至不会增加

您希望在循环内递减val,并且您可能希望将x初始化为1并返回x而不是val

试试这个:

#include <stdio.h>
#include <stdlib.h>

int bar(int val) {
    int x = 1;
    while (val > 0) {
        x += bar(--val);
    }
    return x;
}

int main(int argc, char *argv[]) {
    if (argc > 1) {
        for (int i = 1; i < argc; i++) {
            int v = atoi(argv[i]);
            printf("bar(%d) = %d\n", v, bar(v));
        }
    } else {
        for (int i = 0; i < 20; i++) {
            printf("bar(%d) = %d\n", i, bar(i));
        }
    }
    return 0;
}

输出:

bar(0) = 1
bar(1) = 2
bar(2) = 4
bar(3) = 8
bar(4) = 16
bar(5) = 32
bar(6) = 64
bar(7) = 128
bar(8) = 256
bar(9) = 512
bar(10) = 1024
bar(11) = 2048
bar(12) = 4096
bar(13) = 8192
bar(14) = 16384
bar(15) = 32768
bar(16) = 65536
bar(17) = 131072
bar(18) = 262144
bar(19) = 524288

计算2的权力的复杂,耗时,令人惊讶的方法。

  • 由于递归调用,空间复杂度 O(n)
  • 时间复杂度 O(2 n 使其成为编译和解释语言基准的良好候选者:bar(30)在我的笔记本电脑上花费近3秒钟({ {1}})。

答案 3 :(得分:0)

以下是可能有助于解释的事件的可视化(表达式np.sum(row[2:5]) == 0val将替换为每次迭代的实际值):

val - 1

希望现在问题很明显 - 当bar(3): while ( 3 > 0 ) { x = x + bar(2); } bar(2): while ( 2 > 0 ) { x = x + bar(1); } bar(1): while ( 1 > 0 ) { x = x + bar(0); } bar(0): return 0; bar(1); while ( 1 > 0 ) { x = x + bar(0); } bar(0): return 0; bar(1): while ( 1 > 0 ) { x = x + bar(0); } bar(0); return 0; 返回时,bar(0)再次为val,因此1中的循环再次执行。

可能想要用bar(1)替换while - 这样,执行顺序是

if