代码之家  ›  专栏  ›  技术社区  ›  noobzilla

基本C++递归程序问题

  •  1
  • noobzilla  · 技术社区  · 16 年前
    //This program finds the GCD of two numbers using a recursive function call via the
    //Euclidean algorithm
    
    #include <iostream>
    #include <cmath>
    using namespace std;
    
    int GCD (int A, int B);
    
    int main()
    {
        int A = 45, B = 55;
    
        cout << "The GCD is " << GCD(A,B) << endl;
        //test
        return 0;
    }
    
    int GCD (int A, int B)
    {
        A = abs(A);
        B = abs(B);
    
    
        if (A > B)
        {
            A = A - B;
            return GCD (A, B); //Recursive function call - works fine
            //GCD (A, B);  -- This function call seems to return an incorrect value
    
        else if (A < B)
        { 
            B = B - A;
            return GCD (A, B);//Recursive function call
            //GCD (A, B); -- This function call seems to return an incorrect value
        }
    
        else if (A = B)
        {
            return A;
        }
    }
    

    我的问题是:我注意到,如果在递归函数调用中不使用“return”关键字,程序将返回错误的值,但如果我单步执行函数,则本地函数中的值将正确更新。我知道函数(除非它们是void类型)必须返回一个值。也许这条规则也适用于递归函数调用?

    有人能详细说明/帮助我理解吗?

    6 回复  |  直到 16 年前
        1
  •  7
  •   Konrad Rudolph    16 年前

    也许这条规则也适用于递归函数调用?

    为什么要适用不同的规则?递归函数起作用 确切地 就像正常功能一样。

    顺便说一下,您的程序包含一个错误:

    else if (A = B)
    {
        return A;
    }
    

    这不是一个比较,这是一个任务,而且测试是不必要的,因为所有其他条件( A < B A > B )已经过测试了。

        2
  •  3
  •   mmmmmmmm    16 年前

    如果不返回值,那么返回的值是未定义的。因此,如果if/else if都不匹配,则返回一个不可预测的值(取决于编译器/编译器标志/运行程序的时间/…)。 因此,调用方法将计算错误的结果。

    对于递归和非递归的方法和函数来说都是如此。

        3
  •  1
  •   sepp2k    16 年前

    我知道函数(除非它们是void类型)必须返回一个值。也许这条规则也适用于递归函数调用?

    是的。如果不使用return语句,则函数的返回值未定义。

        4
  •  1
  •   Noordeen xiyurui    7 年前

    解决这个问题的方法是嵌套函数调用。外部 GCD 呼唤内心 GCD ,这反过来又称为内部 GCD A == B )你会的 return A ,该返回将在所有返回值中传播,直到到达最外层 GCD ,将返回正确的值。如果没有回报,最内心的呼唤的结果永远不会传递给外部世界。

    试着写下函数对简单值的作用,你会看到这种嵌套行为。

    编辑:如果你一直在使用Lisp,你可能会感到困惑,因为Lisp会自动返回函数的最后一行。

        5
  •  0
  •   Tall Jeff    16 年前

    return GCD(A,B); 版本,调用的结果 GCD(A,B) 返回给父对象。如果你跳过 return 语句,则返回的结果将丢失,并且不会传递给 GCD() .

    也就是说,在“C”中,必须使用 回来 用于函数返回值的语句。

        6
  •  0
  •   Noordeen xiyurui    7 年前

    " "

    当然,递归不是特例。函数需要返回一些东西,在本例中,需要返回的是递归调用的返回值。

    还有一个无声的错误:你写了 (A=B) 代替 (A==B)