跟踪递归函数

时间:2018-04-27 22:34:18

标签: c recursion

以下程序的输出如下所示: n = 2 n = 1 n = 0 n = -1 n = 0 n = 1

我可以通过程序直到它打印出n = -1的程度,但是为什么它会重新打印并在结束时打印n = 0和n = 1?

public List<DealResponse> GetDealResponse(string detailId)   
{
    // My main confusion is while doing union how to handle the case 
    // which I mentioned (On duplicate select entry from second list)  
    var L3 = L1.Union(L2, new DealResponseComprarer()).ToList();         
}  

public class DealResponse
{
    public string detailId { get; set; }
    public string detailcd { get; set; }
    public string fileName { get; set; }
    public string isNgo { get; set; }
}

public class DealResponseComprarer : IEqualityComparer<DealResponse>
{
    public bool Equals(DealResponse x, DealResponse y)
    {
        return x.detailId == y.detailId &&  x.detailcd == y.detailcd ;
    }

    public int GetHashCode(DealResponse obj)
    {
        return (obj.detailId.GetHashCode() + obj.detailcd.GetHashCode());
    }
}

3 个答案:

答案 0 :(得分:1)

函数中有两个printf,序列中有最后一个printfsn = -1 n = 0 n = 1) 通过第二次printf电话打印,这就是它再次上升的原因。你忘记了那一个。什么时候 递归结束,函数返回上一级并继续 从那里。

最终n--执行了n==0n变为否定,n >= 0正在评估 为false,countdown(n)不再执行。这是终端案例。 这意味着该函数停止调用自身并继续执行下一个语句,这是第二个 printf,将打印n = -1

然后函数返回,最后一个继续,执行第二个 printf您得到n = 0。然后函数结束并返回第一个函数 级别,执行第二个printf并获得n = 1。那么 函数返回main

如果你在递归中稍微更改printf s,你会看到 为什么你得到输出。试试这个:

void countdown (int n)
{

    printf("[1] n = %d\n", n);

    n--;

    if (n >= 0)

    {

            countdown(n);

    }

    printf("[2] n = %d\n", n);

}

现在输出

[1] n = 2
[1] n = 1
[1] n = 0
[2] n = -1
[2] n = 0
[2] n = 1

答案 1 :(得分:1)

每次调用倒计时函数时都会执行两个printf语句(在递归倒计时()调用之前和之后执行一次)。

这里有点难以说明,但让我们来看看你的countdown()函数是如何被执行的,并记住在这种情况下,变量n是其相关函数范围的本地,这意味着每次出现“n”每个countdown()函数调用都独立于另一个。

countdown(2) <- spawns a new execution scope; let's call it S0
  => prints "n=2"
  => sets n=1 in scope S0
  => calls countdown(1) <- spawns a new execution scope; let's call it S1
    ----Inside S1----
    => prints "n=1"
    => sets n=0 in scope S1
    => calls countdown(0) <- spawns a new execution scope; let's call it S2
      ----Inside S2----
      => prints "n=0"
      => sets n=-1 in scope S2
      => if condition fails
      => prints "n=-1"
      => returns execution to scope S1
    => prints "n=0" (which is the value "n" has in scope S1)
    => returns execution to scope S0
  => prints "n=1" (which is the value "n" has in scope S0)
  => execution returns to main() function and program terminates

答案 2 :(得分:0)

对于n = 1n = 0,堆栈位置将保存到临时停止功能的位置。在n=-1情况之后,堆栈从保存的位置返回。这就是为什么你再次使用反序的n = 0n = 1。我建议你看一下stack结构,从而掌握递归逻辑。