#include <stdio.h>
void PrintNumPattern(int x, int y)
{
if (x > 0)
{
printf("%d ", x);
PrintNumPattern(x - y, y);
printf("%d ", x);//idk why this makes it work...why does it add?
} else {
printf("%d ", x);
}
}
int main(void) {
int num1;
int num2;
scanf("%d", &num1);
scanf("%d", &num2);
PrintNumPattern(num1, num2);
}
所以目前我正在学习递归和它是如何工作的。上面的代码应该得到一个输入,例如,12, 3
,然后输出12 9 6 3 0 3 6 9 12
。到目前为止,我很困惑。为什么我加了注释的printf,在0之后开始加?程序只被告知要做减法而不是加法。还有,程序怎么知道要在12处停止呢?
开始在0后加?
它从不添加任何内容。只是在第一个条件中有两个printf
调用打印相同的数字-一次在递归调用之前,一次在递归调用之后。
程序怎么知道在12
递归调用在0处停止。然后返回到父调用,父调用将打印它的编号。
如果你把调用树写出来会有帮助。我试着把它形象化如下图所示。每个缩进表示来自父函数的函数调用。在右列中,我显示了结果输出。
PrintNumPattern(12, 3)
printf(12) -------------------------> 12
PrintNumPattern(9, 3)
printf(9) ----------------------> 9
PrintNumPattern(6, 3)
printf(6) ------------------> 6
PrintNumPattern(3, 3)
printf(3) --------------> 3
PrintNumPattern(0, 3)
printf(0) ----------> 0
printf(3) --------------> 3
printf(6) ------------------> 6
printf(9) ----------------------> 9
printf(12) -------------------------> 12
另一种可能(也可能没有)有帮助的方法是只可视化递归调用的一个层次。这清楚地表明没有"添加"。但只是重复。
PrintNumPattern(12, 3)
printf(12) -------------------------> 12
PrintNumPattern(9, 3) --------------> 9 6 3 0 3 6 9
printf(12) -------------------------> 12
需要第二次打印的原因是,您希望在直到0的过程中重复打印的内容。看起来像是在添加,但实际上您所做的只是反向重复printf调用。手工或工具的可视化可以帮助建立递归函数的直观。请看这个例子,PrintNumPattern(2, 1)