为什么我的程序的控制流在单步执行阶乘方法时似乎跳来跳去?



我正在自己学习C#,很好奇一个简单的代码是如何运行的。

我在if语句上插入了一个换行符,然后逐行进入其中。我想知道为什么在编译器知道 if 语句为 false 后运行代码时,代码总是回到 if 语句上方的大括号?在true if语句之前,它不会从 else 语句返回结果;当它这样做时,它会来回进入 else 语句,将 1 添加到 num 值以执行阶乘。

谁能更好地向我解释一下?

namespace Factorial
{
    class Program
    {
        static void Main(string[] args)
        {
            NumberManipulator manipulator = new NumberManipulator();
            Console.WriteLine("Factorial of six is :" + manipulator.factorial(6));
            Console.ReadLine();
        }
    }
    class NumberManipulator
    {
        public int factorial(int num)
        {
            int result;
            if (num == 1)
            {
                return 1;
            }
            else
            {
                result = factorial(num - 1) * num;
                return result;
            }
        }                
    }
}

该方法是递归的,因此它将调用自身。

当你调用factorial(6)来计算6*5*4*3*2*1时,它将依次调用factorial(5)来计算5*4*3*2*1的零件并将其乘以6

factorial(5)的调用将反过来调用factorial(4)来计算4*3*2*1并将其乘以5

因此,它将继续调用自身,直到调用factorial(1)并且 if 语句的第一部分结束递归。

当您单步执行代码时,您将看到每个调用的执行跳转到方法的开头,直到您到达最里面的调用,它将开始从所有调用返回。如果您观察调用堆栈,您将看到它随着每个递归级别而增长,然后再次收缩。

public int factorial(int num)
{
....
    result = factorial(num - 1) * num;
....

请注意函数阶乘如何调用自身,尽管每次调用的数字较小。这称为递归,是解决编程中许多问题的重要且有用的方法。

递归的重要方面是它必须结束,否则你会进入无限循环,并用StackOverflowException炸毁你的代码(多么巧合,这个站点被称为 StackOverflow :))

以下代码结束递归。

if (num == 1)
{
    return 1;
}

您还可以在调试时打开call stack window,并观察同一函数如何以不断增长的堆栈调用自身(跳回到函数顶部的原因)。

使用以下代码,它可以工作并已经过测试!实现了两种方法:递归基本因子计算。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication50
{
    class Program
    {
        static void Main(string[] args)
        {
        NumberManipulator manipulator = new NumberManipulator();
        Console.WriteLine("Please Enter Factorial Number:");
        int a= Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("---Basic Calling--");
        Console.WriteLine("Factorial of {0} is: {1}" ,a, manipulator.factorial(a));
        Console.WriteLine("--Recursively Calling--");
        Console.WriteLine("Factorial of {0} is: {1}", a, manipulator.recursively(a));
        Console.ReadLine();
    }
}
class NumberManipulator
{
    public int factorial(int num)
    {
        int result=1;
        int b = 1;
        do
        {
            result = result * b;
            Console.WriteLine(result);
            b++;
        } while (num >= b);
        return result;
    }
    public int recursively(int num)
    {
        if (num <= 1)
        {
            return 1;
        }
        else
        {
            return recursively(num - 1) * num;
        }
    }
  }
}

最新更新