编辑问题以包括所需的行为、特定的问题或错误以及重现问题所需的最短代码。这将有助于其他人回答问题。
#include <stdio.h>
void e(int );
int main( )
{
int a;
a=3;
e(a);
return 0;
}
void e(int n)
{
if(n>0)
{
e(n-1);
n = n-1;
printf("%d" , n);
e(n-1);
n = n-1;
}
}
我不明白这是如何计算为0120的,因为我认为如果它是0,if语句将不会运行……我知道我不擅长编码,但想知道是否有人可以解释它是如何输出0120的。
像这样的简单程序可以通过一些打印来“增强”以供理解。
您的原始:
// original
void e(int n)
{
if(n>0)
{
e(n-1);
n = n-1;
printf("%d" , n);
e(n-1);
n = n-1;
}
}
并且它的输出是相同的(即使使用c编译)
// 0120
这是非常相似的递归代码,还有几个指纹
// with debug prints
void e2(int n, std::stringstream& ss)
{
static size_t seq = 0;
std::cout << "seq=" << ++seq << " e2() " << " n=" << n << std::endl; // invocation sequence
if(n>0)
{
e2(n-1, ss);
n = n-1;
ss << "n= " << n << " " << std::flush;
e2(n-1, ss);
n = n-1;
}
else
std::cout << "seq=" << seq << " e2() else " << n << std::endl;
}
以及使用的调用:
int t267(int argc0)
{
std::cout << "argc0: " << argc0 << std::endl << std::endl;
int a = 3;
std::cout << "\ne()----------------------------" << std::endl;
e(a);
std::cout << "\ne2()----------------------------" << std::endl;
std::stringstream ss;
ss << "e2: " << std::endl;
e2(a, ss);
std::cout << ss.str() << std::endl;
std::cout << "\n----------------------------" << std::endl;
return(0);
} // int t267(void)
一些中间输出:
seq=1 e2() n=3
seq=2 e2() n=2
seq=3 e2() n=1
seq=4 e2() n=0
seq=4 e2() else 0
seq=5 e2() n=-1
seq=5 e2() else -1
seq=6 e2() n=0
seq=6 e2() else 0
seq=7 e2() n=1
seq=8 e2() n=0
seq=8 e2() else 0
seq=9 e2() n=-1
seq=9 e2() else -1
ss捕获所有n=x以更简单的方式报告它们,而不是在调试cout之间交错。ss的输出:
n= 0 n= 1 n= 2 n= 0
注意:这显示与原始数字序列相同
它还显示发生了9次递归调用。(seq=9)
这是你所期望的吗?
…调试打印通常也可以提供足够的信息来观察和修复编码错误。
接下来尝试a=0,或1,或2,或4,…等等。并尝试添加额外的打印。
练习。
并逐步审查中间输出,看看它是如何工作的。
祝你好运。
要理解递归函数,你必须首先认真理解递归:),尽管去阅读维基百科页面和你能找到的任何其他文章。https://en.wikipedia.org/wiki/Recursion
这里要记住的重要一点是,对e的每次递归调用都会增加您的调用堆栈,一旦您返回,您就会从调用堆栈中弹出最后一帧并返回到您上次调用e的位置。
以下是在您的案例中实际发生的步骤以及为什么它会这样做。调试器还将让您完成此操作:)