在C ++中跟踪递归因子函数?

时间:2016-03-21 04:51:05

标签: c++ recursion tracing

稍微运动有困难, 假设我有:

#include <iostream>
using namespace std;

int factorialFinder(int x) {
    if (x==1) {
        return 1;
    }else{
        return x*factorialFinder(x-1);
    }
}

int main()
{
    cout << factorialFinder(5) << endl;
}

你会如何追踪这个? 例如:

Put in 5 into the factorialFinder function.
if (5 == 1) (False, so skip)
returns 5 times factorialFinder(5-1)
this means returns 5 times factorialFinder(4)
this means go back to function
if (4 == 1) (False, so skip)
returns 4 times factorialFinder(4-1)
...etc.

现在,如果你遵循我的逻辑,我的问题就在我最后的陈述中

returns 4 times factorialFinder(4-1)

它返回4还是返回20,因为它首先乘以5 * 4。

抱歉,我无法理解这一点以及为什么会这样。 请尝试以某种方式解释我的逻辑。

2 个答案:

答案 0 :(得分:2)

为了深入理解任何代码的工作原理,您可以打印应用程序运行的步骤

例如:

#include <iostream>
using namespace std;

int factorialFinder(int x) {
    cout << "f: " << x << endl;
    if (x==1) {
        cout << "return 1" << endl;
        return 1;
    }else{
        const int res = x*factorialFinder(x-1);
        cout << "return " << res << endl;
        return res;
    }
}

int main()
{
    cout << factorialFinder(5) << endl;
}

输出是:

f: 5
f: 4
f: 3
f: 2
f: 1
return 1
return 2
return 6
return 24
return 120
120

答案 1 :(得分:2)

生成跟踪的一种方法是检测代码,添加跟踪输出语句。为此创建一些支持是个好主意。如,

#include <iostream>
#include <string>
using namespace std;

auto operator*( int const n, string const& s )
    -> string
{
    string result;
    for( int i = 1; i <= n; ++i ) { result += s; }
    return result;
}

class Tracer
{
private:
    std::string callspec_;
    std::string result_;

    auto call_level()
        -> int&
    {
        static int the_level;
        return the_level;
    }

    static auto indent() -> string { return ".  "; }

public:
    template< class Value >
    auto result( Value v )
        -> Value
    {
        result_ = to_string( v );
        return v;
    }

    ~Tracer()
    {
        --call_level();
        clog << "<- " << call_level()*indent() << callspec_;
        if( not result_.empty() )
        {
            clog << " returns " << result_;
        }
        clog << endl;
    }

    Tracer( string funcname )
        : callspec_( move( funcname ) )
    {
        clog << "-> " << call_level()*indent() << callspec_ << endl;
        ++call_level();
    }
};

auto factorial( int const x )
    -> int
{
    Tracer trace( "factorial " + to_string( x ) );
    return trace.result( x == 1? 1 : x*factorial( x - 1 ) );
}

auto main() -> int
{
    cout << factorial( 5 ) << endl;
}

结果:

-> factorial 5
-> .  factorial 4
-> .  .  factorial 3
-> .  .  .  factorial 2
-> .  .  .  .  factorial 1
<- .  .  .  .  factorial 1 returns 1
<- .  .  .  factorial 2 returns 2
<- .  .  factorial 3 returns 6
<- .  factorial 4 returns 24
<- factorial 5 returns 120
120

然而,只需使用调试器来逐步执行代码,就可以获得更少的工作。