簡體   English   中英

為什么我的程序的控制流程似乎在逐步通過階乘方法時會跳轉?

[英]Why does my program's control flow seem to jump around when stepping through a factorial method?

我正在研究C#,很好奇一個簡單的代碼是如何運行的。

我在if語句中插入了一個換行符並逐行進入。 我想知道為什么代碼在編譯器知道if語句為false后運行代碼時會繼續回到if語句上方的大括號? if語句為true之前,它不會從else語句返回結果; 當它發生時,它來回執行else語句,將num值加1以執行階乘。

任何人都可以向我解釋一下嗎?

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;
....

注意函數factorial如何調用自身,盡管每次調用的數字都較小。 這稱為遞歸,是解決編程中許多問題的重要且有用的方法。

遞歸的重要方面是它必須結束,否則你進入無限循環,並用StackOverflowException炸掉你的代碼( 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;
        }
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM