C++ 我怎样才能创建一个跟踪来显示存在递归的调用顺序
我想知道递归函数执行的细节C++ 我怎样才能创建一个跟踪来显示存在递归的调用顺序,c++,C++,我想知道递归函数执行的细节 #include<iostream> int a=0; int fac(int n) { if (n <= 1) return n; int temp = fac(n-2) + fac(n - 1); a++; return temp; } int main() { fac(4); std::cout<<a; } #包括 int a=0; 国际飞行中心(国际北){ 如果(n
#include<iostream>
int a=0;
int fac(int n) {
if (n <= 1)
return n;
int temp = fac(n-2) + fac(n - 1);
a++;
return temp;
}
int main() {
fac(4);
std::cout<<a;
}
#包括
int a=0;
国际飞行中心(国际北){
如果(n第一个fac(2)将完成,然后是fac(1)。输出为4
调用堆栈如下(从下到上)-
当N纯代码分析时,函数将返回,不涉及C++实现复杂度,
fac(4)
fac(2) + fac(3)
|----------------------------|
fac(0) + fac(1) fac(1) + fac(2)
1 + 1 1 + fac(0) + fac(1)
+ 1 + 1
我怎样才能创建一个跟踪来显示存在递归的调用顺序
首先,我想指出的是,编译器生成的编译器输出不会与您编写的代码一一匹配。编译器根据提供给它的标志应用不同级别的优化,最高级别为-O3
,默认值为-O0
,但这些似乎超出了这个问题的范围。创建跟踪会影响此过程本身,因为编译器现在需要满足您对跟踪外观的期望。跟踪实际执行流的唯一真正方法是读取
知道了这一点,我们可以通过在执行进入被调用方法时打印到屏幕来应用跟踪来查看调用顺序。注意,我删除了a
,因为它实际上没有跟踪任何内容,只会增加解释的复杂性
int fac(int n) {
std::cout << "fac(" << n << ")" << std::endl;
if (n <= 1)
return n;
int temp = fac(n-2) + fac(n - 1);
return temp;
}
int main() {
fac(4);
}
// Output
fac(4)
fac(2)
fac(0)
fac(1)
fac(3)
fac(1)
fac(2)
fac(0)
fac(1)
注意:这并不意味着每个实现的结果都是相同的,也不意味着当您删除跟踪并允许编译器优化时,执行顺序会保持不变,但它演示了递归在计算机编程中的工作方式。我假设您的代码缺少全局int a
Andy,请确保重新编译后的代码。您的问题可能需要阅读“如何创建一个显示递归调用顺序的跟踪?”C++是一种编译语言,因此没有“转换器”它执行代码。编译器将所有内容转换为机器代码,生成可执行文件,然后执行。编译和执行是完全独立的过程。什么是fac_1
?请发布实际编译的真实代码。我基本上检查,在每个递归函数中打印一些内容。例如,在您的代码中,i添加printf(“fac(%d)被称为\n”,n);
在函数的开头。即使运算符求值未定义,这仍然会突出显示递归调用是如何工作的,这是OP的问题。纠缠于+运算符的顺序没有任何意义。唯一的区别是反转此调用树中的节点。您将不得不使用良好的文档来支持这样的声明urce,Faruk.@AvinKavish有权这样做。因为程序的行为不会受到影响,所以先发生哪一个并不重要。据我们所知,没有调用树。编译器可以查看代码,计算最终结果,并为std::coutFrom(emphasis mine)生成代码:“除了下面所指出的,C++中没有左到右或左到右的评价概念,这不应该与操作符的左到右和右到左的关联性混淆:表达式f1(+)+f2()+f3()被解析为(f1(+)+f2())+f3()。由于运算符+(从左到右)的关联性,对f3的函数调用可以在运行时首先、最后或在f1()或f2()之间求值。“没有任何规则规定必须在右运算符之前求值+
运算符的左操作数
int fac(int n) {
std::cout << "fac(" << n << ")" << std::endl;
if (n <= 1)
return n;
int temp = fac(n-2) + fac(n - 1);
return temp;
}
int main() {
fac(4);
}
// Output
fac(4)
fac(2)
fac(0)
fac(1)
fac(3)
fac(1)
fac(2)
fac(0)
fac(1)
// Call order
1. fac(4)
2. fac(2) + 5. fac(3)
|----------------------------|
3. fac(0) + 4. fac(1) 6. fac(1) + 7. fac(2)
+ 8. fac(0) + 9. fac(1)