C中的递归,需要一些解释

时间:2016-07-03 21:59:05

标签: c recursion

我有这段代码:

#include <stdio.h>

void foo(int m, int n)
{
  printf("A: m = %i, n = %i\n", m, n);
  while (m < n)
  {
  foo(m + 1, n - 1);
  n -= 5;
  }
  printf("E: m = %i, n = %i\n", m, n);
}

int main(void)
{
  foo(6, 14);
  return 0;
}
  

我希望代码在m=10n=10之后停止运行,但它不会停止。我不明白为什么我得到输出:

A: m = 6, n = 14
A: m = 7, n = 13
A: m = 8, n = 12
A: m = 9, n = 11
A: m = 10, n = 10
E: m = 10, n = 10 // I expected program to stop here
E: m = 9, n = 6
E: m = 8, n = 7
A: m = 8, n = 7
E: m = 8, n = 7
E: m = 7, n = 3
A: m = 7, n = 8
A: m = 8, n = 7
E: m = 8, n = 7
E: m = 7, n = 3
E: m = 6, n = 4

有人能解释为什么这是输出吗?

1 个答案:

答案 0 :(得分:2)

在调试器中运行程序应该澄清您的疑虑。或者甚至添加一些额外的printf可以帮助查看正在发生的事情。但仍然让我为此尝试。

foo(6, 14) expands to:
======================
Prints "A: m = 6, n = 14"
Calls foo(7, 13);  -- (i)
Calls foo(7, 8);   -- (ii)
Prints "A: m = 6, n = 4"

So to know the final output, we need to see what 
    foo(7, 13) -- (i), and 
    foo(7, 8)  -- (ii)
expand to. 

让我们一步一步看。让我们处理(i),即foo(7,13 first)

Call to foo(7,13)  <--> expanding (i) 
=====================================
Prints "A: m = 7, n = 13"
Calls foo(8, 12)   -- (iii)
Calls foo(8, 7)    -- (iv)
Prints "A: m = 7, n = 3"

Call to foo(8,12)  <--> expanding (iii)
=======================================
Prints "A: m = 8, n = 12"
Calls foo(9, 11)   -- (v) 
Prints "A: m = 8, n = 7"

Call to foo(9,11)  <--> expanding (v) 
=======================================
Prints "A: m = 9, n = 11"
Calls foo(10,10)  -- (vi)
Prints "A: m = 9, n = 6"

Call to foo(10,10)  <--> expanding (vi)
=======================================
Prints "A: m = 10, n = 10"
Prints "A: m = 10, n = 10"

Now, substituting (vi) in (v), foo(9, 11) expands to
===================================================
Prints "A: m = 9, n = 11"
Prints "A: m = 10, n = 10"
Prints "A: m = 10, n = 10"
Prints "A: m = 9, n = 6"

Now, substituting (v) in (iii), foo(8, 12) expands to
=====================================================
Prints "A: m = 8, n = 12"
Prints "A: m = 9, n = 11"
Prints "A: m = 10, n = 10"
Prints "A: m = 10, n = 10"
Prints "A: m = 9, n = 6"
Prints "A: m = 8, n = 7"

Coming back to (iv), call to foo(8, 7) <--> expanding (iv)
==========================================================
Prints "A: m = 8, n = 7"
Prints "A: m = 8, n = 7"

Now, subsituting (iii) and (iv) in (i), i.e. foo(7, 13) expands to - call it "part A"
==============================================================================
Prints "A: m = 7, n = 13"
Prints "A: m = 8, n = 12"
Prints "A: m = 9, n = 11"
Prints "A: m = 10, n = 10"
Prints "A: m = 10, n = 10"
Prints "A: m = 9, n = 6"
Prints "A: m = 8, n = 7"
Prints "A: m = 8, n = 7"
Prints "A: m = 8, n = 7"
Prints "A: m = 7, n = 3"

好的,部分(i),即foo(7,13)完成。让我们处理第(ii)部分,即foo(7,8)     现在:

Call to foo(7, 8) <--> expanding (ii)
=====================================
Prints "A: m = 7, n = 8"
Calls foo(8, 7)    -- (vii)
Prints "A: m = 7, n = 3"

Call to foo(8, 7)  <--> expanding (vii)
=======================================
Prints "A: m = 8, n = 7"
Prints "A: m = 8, n = 7"

Substituting (vii) in (ii), foo(7,8), i.e. (ii) expands to - call it "part B"
============================================================================
Prints "A: m = 7, n = 8"
Prints "A: m = 8, n = 7"
Prints "A: m = 8, n = 7"
Prints "A: m = 7, n = 3"

好的,第(ii)部分,即foo(7,8)也完成了。所以,现在我们知道了 什么(i)和(ii)扩展到,我们可以知道最终的输出:

Call of foo(6, 14), expands to
==============================
"A: m = 6, n = 14"
Part "A"
Part "B"
"A: m = 6, n = 4"

i.e. as follows:

"A: m = 6, n = 14"
"A: m = 7, n = 13"
"A: m = 8, n = 12"
"A: m = 9, n = 11"
"A: m = 10, n = 10"
"A: m = 10, n = 10"
"A: m = 9, n = 6"
"A: m = 8, n = 7"
"A: m = 8, n = 7"
"A: m = 8, n = 7"
"A: m = 7, n = 3"
"A: m = 7, n = 8"
"A: m = 8, n = 7"
"A: m = 8, n = 7"
"A: m = 7, n = 3"
"A: m = 6, n = 4"

如果这个解释没有引起混淆,那么你应该能够看到为什么你得到的输出是预期的。

我想,由于以下原因,您缺少剩余的打印声明:

- 你忽略了while循环之后的print语句,当foo从下面的某个级别返回时执行。