我在 C 语言中有一个递归函数,我试图理解为什么它以这种方式打印:
void rec(int x, int y){
if (x == y)
return;
rec(x--, y+1);
printf("%3d%6.2fn", x, (float) y);
}
我知道 rec(8,4( 的输出是:
7 7.00
7 6.00
7 5.00
7 4.00
为什么X
值保持 7?据我了解,x--
应该只发生在写入的行之后。如果不是,为什么值保持 7 而不是减少? 还有为什么y
值在减小?因为它在递归停止时开始打印?
我对C很陌生,不习惯所有需要注意的小细节(我来自java(
感谢您的任何帮助!
这不是语法问题,而是递归和调用堆栈的问题。
首先:执行rec(x--, y+1)
将 x 的原始值传递给函数,函数完成后,x 被修改(但修改永远不会保存(。如果你像这样传递它,y 也会发生同样的情况:rec(x--, y++)
.这样做的"正确"方法是在计算函数之前更改值,就像您之前对 y 所做的那样,或者像这样:rec(--x, ++y)
.
完成此操作后,您将看到 y 正在去皱,x 在折痕中。为什么? 因为调用堆栈。最后调用的函数将首先完成。为此,您可以将调用函数想象为只是复制粘贴已设置参数的代码。然后它看起来像这样:
void rec(int x, int y){
if !(x == y)
rec(--x, ++y);
printf("%3d%6.2fn", x, (float) y);
}
...
if !(4 == 0){
if !(3 == 1)
if !(2 == 2)
rec(--x, ++y);} // we are done now, no more "code is inserted"
printf("%3d%6.2fn", 2, (float) 2);
printf("%3d%6.2fn", 3, (float) 1);
printf("%3d%6.2fn", 4, (float) 0);
对于y
部分,这是因为您在递归调用后打印,因此结果将以相反的顺序打印(最后一次调用在前,第一次调用在后(。
对于x
部分,正是因为您使用的是后递减。当调用rec
时,它传递了之前传递的值,然后递减。因此,您总是将8
传递给递归调用,然后递归调用会递减,当递归结束时,它最终会打印7
。
当使用后缀递减运算符x--
时,表达式的值是应用递减之前变量的值。这意味着 x 的值只有在完成所有子递归调用后,在每次rec
调用中才会实际递减。这就是为什么你会看到每一步都打印7
- 每个函数都会执行递减并打印它,但8
传递给子函数。
但是,如果要在递减运算符--x
前面加上前缀,则该值将是应用赋值后变量的值。这将为您提供所需的结果,其中变量随着每次递归调用而递减。您还可以执行对 y 变量执行的操作,并指定x - 1
而不是x--
。
X:这是因为您在rec
调用中使用后递减。它的作用是首先将 X 的当前值传递给调用,然后递减 X:
rec(x--, y+1);
相当于:
rec(x, y+1); x-=1;
Y:你在递归调用之后打印,所以第一个打印的将是rec
的"最后一个"调用,因此y值最高。