无法理解“返回”的工作原理

时间:2016-06-11 14:53:59

标签: c++ return

我正在研究以下代码,目的是在扩展的Euclid算法中找出x和y的解决方案:

long gcd(long a, long b, long &x, long &y) {
    long d; // place to hold final gcd
    // in case b = 0, we have d=|a|, x=1 or -1, y arbitrary (say, 0)
    if (b==0) {
        if (a<0) {
            d = -a;
            x = -1;
            y = 0;
        } else {
            d = a;
            x = 1;
            y = 0;
        }
        return d;
    }
    // if b is negative, here is a workaround
    if (b<0) {
        d = gcd(a,-b,x,y);
        y = -y;
        return d;
    }
    // if a is negative, here is a workaround
    if (a<0) {
        d = gcd(-a,b,x,y);
        x = -x;
        return d;
    }
    // set up recursion
    long aa = b;
    long bb = a%b;
    long qq = a/b;
    long xx,yy;
    d = gcd(aa,bb,xx,yy);
    x = yy +1;
    y = xx - qq*yy;
    return d;
}

我真正不明白的是'返回'是如何工作的。 给定两个输入数字(a,b),我试图遵循所有查看调试会话的行为(使用Apple Xcode)。

一旦b == 0,它就在这里:

if (b==0) {
    if (a<0) {
        d = -a;
        x = -1;
        y = 0;
    } else {
        d = a;
        x = 1;
        y = 0;
    }
    return d;
}

从这个'return d'跳转到代码末尾的最后一个'return d'。 在那里,它开始循环最后一块代码:

    d = gcd(aa,bb,xx,yy);
    x = yy +1;
    y = xx - qq*yy;
    return d;
}

直到找到所有解决方案。

我的问题是:

1)为什么从第一个'返回d'开始直接跳到最后'返回''? 2)怎么可能从那里到最后四行直到结束而不是调用函数

d = gcd(aa,bb,xx,yy);

之前做过什么?

这里我也发布了主要内容:

int main() {

    long a,b,x,y;

    cout << "Insert first ---> ";
    cin >> a;

    cout << "Insert second ---> ";
    cin >> b;




    cout << "The gcd of " << a << " and " << b << " is "
         << gcd(a,b,x,y)<<endl;

    cout << "x is " << x << " and y is " << y << endl;

    return 0;
}

非常感谢

2 个答案:

答案 0 :(得分:0)

主要是顺序调用吗?这是我能够理解它会做到这一点的唯一原因。例如:

            <EditText
                android:layout_width="30dp"
                android:layout_height="match_parent"
                android:ems="10"
                android:id="@+id/editText_code"
                android:layout_marginLeft="20dp"
                android:background="@android:color/transparent"
                android:hint="+91"
                android:textSize="14sp"
                android:phoneNumber="true" />


      <EditText
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:hint="MOBILE NO"
                android:singleLine="false"
                android:layout_below="@+id/linearLayoutFirstName"
                android:layout_toRightOf="@+id/linearLayoutFirstName"
                android:layout_toEndOf="@+id/linearLayoutFirstName"
                android:background="@android:color/transparent"
                android:layout_gravity="center"
                android:textSize="12sp"
                android:layout_marginLeft="05dp"
                android:id="@+id/mobileNo"
                android:phoneNumber="true" />
        </LinearLayout>

理论上,这会导致第一个if语句为真,并且如此评估,但是第二次调用gcd将绕过所有if语句并直接进入底部。

编辑:我想我真的不明白这个问题,不应该试图回答。但是,我所知道的是,从提供的代码中,gcd在调用时可以采用四种可能的路径:

  1. long g1 = gcd(3, 0, x, y); long g2 = gcd(3, 2, x, y); 如果b==0为负数,则返回a的绝对值并设置x = -1。如果不是,则设为a
  2. b<0这将返回对gcd的调用结果,其绝对值为b,并取消通过引用传递的y变量。
  3. a<0与路径2相同,但ax代替by
  4. 以上都不是真的,并且发生了奇怪的事情(我没有必要使用这个算法(我知道,我是一个简单的人))。
  5. 这可能不能很好地回答你的问题,但这就是我总是打破这些类型的问题以便进行分析和故障排除,所以我希望它有一些用处,至少可以引导你一步一步如果您尚未使用它,请使用故障排除方法。

答案 1 :(得分:0)

  1. 当你从return d;步进时,你应该在函数的末尾结束,这是它的右括号。

    如果你开始将结束括号放在他们自己的一行上,你将能够区分“最后一个语句”和“函数结束”之间的区别。

  2. 递归函数的工作方式与非递归函数完全相同 - 每次调用都会在调用之后立即返回;在您的情况下,对gcd(aa,bb,xx,yy);的每次调用都将返回到行x = yy +1;,这就是您认为这些行被循环的原因。

    (如果你打开调试器的callstack窗口,你会看到它随着函数的调用而增长,并在你从它们返回时收缩,而你的“循环”就是在几个单独的中返回到同一个点函数调用。)