我有这段代码:
#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=10
和n=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
有人能解释为什么这是输出吗?
答案 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
从下面的某个级别返回时执行。