有么有大牛 表达能力强的给我讲下递归啊 是在看不懂他怎么执行的?跳来跳去
 static string Test(int i)
        {
            if (i == 10)
            {
                return i.ToString();//①
            }
            else
            {
                Test(++i);
                return i.ToString();//②
            }
        }Console.WriteLine(Test(1));  结果居然是2,
1.为什么第①出 return不跳出?
2.当满足条件后执行else的 ② 为什么他也不出去,++居然成了--了 ,还有他为什么减到2才执行完?条件在哪里不单单是这个例子 就大牛们帮忙解释下关于递归或许更麻烦的例子

解决方案 »

  1.   

    你的Test(int i)
    实参i 在一次运行后进入到else只会进行一次++操作 所以1=》2因为传入的是值类型 传入的始终是值而非内存地址 下次循环时就是用的另一个int  i 
      

  2.   

    这根本不算递归,方法首次传入参数是1,第一个if不满足,因为1小于10,进到else里面,++i,此时i是2,虽然再次调用了Test,但不处理返回值,而且参数值类型传入的是副本,任你里面怎么处理,外面还是不变,最后i.ToString,就是‘2’。
      

  3.   


            static string Test(int i)
            {
                if (i == 10)
                {
                    return i.ToString();//①  //如果i大于10了,就不在递归了,返回i
                }
                else   //只要i的值小于10,就以++i作为参数递归,此时i的值+1了
                {
                    Test(++i);
                    return i.ToString();//②
                }
            }
      

  4.   

    你输入1显示2怎么是--呢?你都return了不就结束了?
      

  5.   

    你将return i.ToString() 改为Console.Write(i.ToString()) 可以看到
    传入小于10的数 最终都会止步于10 
    大于10的话就成了死循环了
      

  6.   

    不对吧?不大于10他也不递归了才对,因为他在else里面return了
      

  7.   

    还好理解
     static string Test(int i)
            {
                if (i == 10)
                {
                    return i.ToString();//①  //如果i大于10了,就不在递归了,返回i
                }
                else   //只要i的值小于10,就以++i作为参数递归,此时i的值+1了
                {
                    Test(++i); //小于10就递归了 而没有执行下面的return 从1-10 然后到10后 会执行上面if   最后执行return i.ToString();//② 
                    return i.ToString();//② 
                }
            }
      

  8.   

    看到这么多人回复 很感动,但是我真的还没搞明白。
    {
    这根本不算递归,方法首次传入参数是1,第一个if不满足,因为1小于10,进到else里面,++i,此时i是2,虽然再次调用了Test,但不处理返回值,而且参数值类型传入的是副本,任你里面怎么处理,外面还是不变,最后i.ToString,就是‘2’。}但是我单步调试的话,他会进到①里边,这时候为什么不跳出?
    另外单步调试 当i==10执行完return i.ToString()。他会直接跳到最后一个大括号,然后返回
    Test(++i) 然后一直执行 Test (++i) 和 return i.ToString()和最后一个大扩好,然后 i的值从10一直退到2,我只是想了解他的执行过程,他什么会这样执行,递归原理是啥,
      

  9.   

    我纠正下,有些回答可能会让你理解偏差。这个程序算递归,判断递归的原则很简单,就是看程序有没有调用自己。其实递归没有什么神秘的,只是自己调用自己会有些让人觉得混淆。如同
    foo()
    {
    int i = 3;
    bar(3);
    }
    bar(int x)
    {
    int i; //这个i和foo中的i无关,不难理解吧
    }
    一样,
    如果自己调用自己,那么下一层调用内的变量和上一层也没有关系。
      

  10.   

    首先 你不知道对栈是否了解 每次调用 都会生产新的i在栈顶 每次return 都会让这个i退栈 但是由于i是值类型 所以说你看到的所谓i从10减到2不是在执行--操作 而是说这个i本身并没有被改变 而是在递归调用的时候传了一个复制进去 所以最终输出的只是++i的结果
      

  11.   

    是会进到①里,但是进到①时的调用方并不是你的 Console.WriteLine(Test(1)) ,是 Test 方法,所以 跳出跳到 Test 方法里去了,而 Test 又不处理这个跳出的结果,等于说是这个结果被直接扔掉了,你在最外部的代码得不到这个值。
      

  12.   

     static string Test(int i)
            {
                if (i == 10)
                {
                    return i.ToString();//①  //如果i大于10了,就不在递归了,返回i
                }
                else   //只要i的值小于10,就以++i作为参数递归,此时i的值+1了
                {
                    Test(++i);
                    return i.ToString();//②
                }
            }
      

  13.   

    static string Test(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test2(++i);
            return i.ToString();//②
        }
    }static string Test2(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test3(++i);
            return i.ToString();//②
        }
    }static string Test3(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test4(++i);
            return i.ToString();//②
        }
    }static string Test4(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test5(++i);
            return i.ToString();//②
        }
    }static string Test5(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test6(++i);
            return i.ToString();//②
        }
    }static string Test6(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test7(++i);
            return i.ToString();//②
        }
    }static string Test7(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test8(++i);
            return i.ToString();//②
        }
    }static string Test8(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test9(++i);
            return i.ToString();//②
        }
    }static string Test9(int i)
    {
        if (i == 10)
        {
            return i.ToString();//①
        }
        else
        {
            Test10(++i);
            return i.ToString();//②
        }
    }static string Test10(int i)
    {
        return i.ToString();//①
    }这个方法执行时展开就是上面这些,你把这些加到代码里替换原先的 Test 方法,执行 Console.WriteLine(Test(1)) ,单步看运行过程你就明白了
      

  14.   

    听上面这么多人说我明白了,i为什么是2,但是 当i满足条件为什么不跳出? return i.ToString();//① 他没有跳出这段函数Test(++i); 
    return i.ToString();//②                
             }
    当i满足10时候他会重复执行这一段, 等于return了 多次都没有跳出,但最终他跳出了 这时候i=2,想知道他为什么多执行了这么多次 还有i=2 时候怎么跳出了?为什么呢?
      

  15.   

    他不是没有跳出 建议你在
    if (i == 10)
      {
      return i.ToString();//①
      }里面加一个这个
    throw new Exception() 然后看一下StackTrack 也就是堆栈跟踪
      

  16.   

    递归顺序
    Test(1) i = 2 -> Test(2) i = 3 -> ...  Test(9) i = 10 -> Test(10)
    返回值
    Test(10) i = 10 return 10 -> Test(9) i = 10 -> return 10 -> Test(8) i = 9       return 9  Test(7) -> ...-> Test(2) i = 3 return 3 -> Test(1) i = 2 -> return 2 -> 主线程调用函数所以结果就是2
      

  17.   

    想要输出10可以这么写        static string Test(int i)
            {
                return i == 10 ? i.ToString() : Test(++i);
            }        Console.WriteLine(Test(1));//输出10
      

  18.   

    我晕avphoenixi给的例子我刚明白一点点,我看你这个  
      static string Test(int i)
            {
                return i == 10 ? i.ToString() : Test(++i);
            }        Console.WriteLine(Test(1));//输出10
    怎么有晕了 
    他不是和 if  else 相等么 他怎么会输出10呢??
      

  19.   

    递归的运行机制是先递(正向循环,直至结束条件满足为止,本例中的i==10,到此完成了递),后归(就是你所说else里的多次运行,其实是回朔,递归完了在回朔这是递归的机制,回朔的过程就是出栈计算数据的过程)至于本例中为啥会返回结果是2那是因为你的i只是对于方法内部有效,外部是无效的理解了递归的两个过程及入栈出栈过程这个问题其实很好解释
      

  20.   

    return i.ToString();//② 去掉
      

  21.   

    你的代码没有处理返回值,所以代码
    Console.WriteLine(Test(1)); 
    输出的是最后一次返回的字符串,这最后一次就是2.
    如果你希望得到10,9,8,7,6,5,4,3,2,1的输出结果,代码应该这样:
    static string Test(int i)
    {
       return (i == 10) ? i.ToString() : Test(i + 1) + "," + i.ToString();
    }
      

  22.   

    return Test88(++i) + "," + i.ToString();
    却是是返回了10,10,9,8,7,6,5,4,3,2
    为什么之前的I他没有保存了值 是因为他是值类型,每次递归传递的只是他的副本,那么这个该如何解释呢,他为什么返回了这么一串,
    我知道他是字符串,引用类型,但是看不到他叠加啊,那么这个递归拆分开来用22楼回答的这种理解,应该是什么形式
      

  23.   

    一句话,你根本没有明白!
    仔细看你原先的代码,执行Test(++i);的时候,的确会返回一个值,但是却没有捕获而直接丢弃了,而你后面给的几种写法都对Test(++i)的返回值进行了捕获,这才是差别。换句话说,最初的代码因为没有捕获返回值,这种递归毫无意义。
      

  24.   

    建议楼主看一下什么是值类型和引用类型 由于int是值类型,你传入方法里面改变值 根本不会影响它原来的值,还有,递归就是自己调自己,不是你说的return之后它没有跳出,像楼上说的test1,test2..... 
      

  25.   

    帮你把程序修改了下,帮助理解,希望对你有用
     static string Test(int i)
            {
                Console.WriteLine(i);
                if (i == 3)
                {
                    return i.ToString();//①
                }
                else
                {
                    Test(i+1);
                    Console.WriteLine(i);
                    return i.ToString();//②
                }
            }
      

  26.   

    这个例子四个很糟糕的递归例子,对初学者会造成困扰。递归思想跟一个人受到的“数学归纳法”或者“形式逻辑解析方法”的训练息息相关。最初理解归纳方法时,我们都习惯于直观地看到收敛的效果。而这个题目却是以T(n)=T(n+1); T(10)=N;这种形式,跟任何一种经典的归纳法表达式相比,它都没有强调收敛并结束递归的效果。