为什么 --x; 在递归代码中能够工作,而 x-- 会导致段错误?

3

这段代码导致了一个段错误,但是当我将 x-- 改为 --x 时,它打印出了正确的结果。

它们不是一样的吗???

int main()
{    
    myFunc(5); 
    return 0;
}

void myFunc (int x) {  
    if (x > 0) {
        myFunc(x--);
        printf("%d, ", x);
    }
    else
        return;
}

1
哎呀,栈溢出的情况!! - another.anon.coward
@another.anon.coward 在这种情况下,令人惊讶的是没有。MSVC能够将其视为尾递归...编辑:我收回之前的说法。您必须将printf()移动到函数调用的开头(就像我的答案中一样),才能使它成为尾递归。 - Mysticial
@Mysticial:哦...但通常无限递归不是堆栈溢出的常见原因之一吗?正如你所说,也许编译器会将这种情况优化为尾递归。 - another.anon.coward
4个回答

13

不,它们不一样。

x----x 的区别在于返回值是在递减之前还是之后。

myFunc(x--) 中,x-- 返回旧值。 因此,myFunc() 会重复调用相同的值-> 无限递归。

myFunc(--x) 中,--x 返回新值。 因此,myFunc() 每次都会以递减的数字调用-> 没有无限递归。


如果您将 printf 移到函数调用的开头,则更容易看到此情况:

void myFunc (int x) {  
    printf("%d, ", x);

    if (x > 0) {
        myFunc(x--);

    }
    else
        return;
}

输出:(当输入为10时)

10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, ...

5

后置递减操作(x--)在参数计算完成之后进行,因此myFunc将以同一个值重复调用。而前置递减操作(--x)在参数计算之前进行,可以按预期运行。


3

因为--的修改是后缀或前缀。当你调用x--时,它是后缀,因此在调用myFunc之后运行,在这种情况下什么都不做。--x将在myFunc之前被调用,因此会影响x。


1

x--在使用后递减变量。这就是为什么你总是向函数传递相同的值,该值应递减,但实际上并没有递减,因此函数会重复执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接