2016-03-21 21 views
0

biraz egzersiz ile sorun mu yaşıyorsunuz, Ben varsayalım:C++ 'da yinelemeli bir faktöriyel fonksiyonun izlenmesi?

#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; 
} 

Bunu nasıl iz ki? Örneğin : sen benim mantığı izlerseniz

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. 

Şimdi sorum

returns 4 times factorialFinder(4-1) 

o 4 çıkmıyor veya ilk 5 * 4 çarpar çünkü 20 çıkmıyor benim son açıklamada ise.

Üzgünüm, bunu anlamakta zorlanıyorum ve neden bu işe yarıyor. Lütfen mantığımı bir şekilde kullanmayı açıklamaya çalışın. herhangi bir kod uygulaması Örneğin

çalışır nerede, sen adımları yazdırabilir nasıl çalıştığını derin anlamak için

+0

Kendinizin '1' için çalışıp çalışmadığını sorun. 2 için mi? Herhangi bir "n" için çalışıyorsa, n + 1 için çalışır (şu an için taşmaları göz ardı eder. –

+0

Bu, 24 döndürür. En dıştaki işlevin 5 * 24 = 120 değerini hesaplar ve –

+1

döndürür. Belki kodunuzu makinenizden ayıklayabilirsiniz, daha kolay anlaşılır ... –

cevap

2

Tek yön izleme, izleme çıktı ifadeleri ekleyerek kodu alete kodudur. Bunun için biraz destek oluşturmak iyi bir fikir olabilir. Ör

#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; 
} 

Sonuç: Ancak

 
-> 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 

, sadece adım kod adım çok daha az çalışma ile tıpkı aydınlatıcı olabilir yürütmek için bir ayıklayıcısını kullanarak.

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; 
} 

Ve çıkış: a oluşturmak için

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