本章内容:
方法的结构
方法体内部的代码执行
局部变量
局部常量
控制流
方法调用
返回值
返回语句和void方法
局部函数
参数
值参数
引用参数
引用类型作为值参数和引用参数
输出参数
参数数组
参数类型总结
方法重载
命名参数
可选参数
栈帧
递归
栈帧
至此,我们已经知道了局部变量和参数是位于栈上的,下面深入探讨一下其组织。
在调用方法的时候,内存从栈的顶部开始分配,保存和方法关联的一些数据项。这块内存叫
作方法的栈帧(stackframe)。
- 栈帧包含的内存保存如下内容。
- 返回地址,也就是在方法退出的时候继续执行的位置。
- 分配内存的参数,也就是方法的值参数,还可能是参数数组(如果有的话)。
- 到和方法调用相关的其他管理数据项。
- 在方法调用时,整个栈帧都会压入栈。
- 在方法退出的时候,整个栈帧都会从栈上弹出。弹出栈帧有的时候也叫作栈展开(unwind)。
例如,如下代码声明了3个方法。Main调用MethodA,MethodA又调用MedhodB,创建了3个
栈帧。在方法退出的时候,栈展开。
class Program
{
static void MethodA(int par1,int par2)
{
Console.WriteLine($"Enter MethodA:{par1},{par2}");
MethodB(11,18);
Console.WriteLine("Exit MethodA");
}
static void MethodB(int par1,int par2)
{
Console.WriteLine($"Enter MethodB:{par1},{par2}");
Console.WriteLine("Exit MethodB");
}
static void Main()
{
Console.WriteLine("Enter Main");
MethodA(15,30);
Console.WriteLine("Exit Main");
}
}

递归
除了调用其他方法,方法也可以调用自身。这叫作递归。
递归会产生很优雅的代码,比如下面计算阶乘数的方法就是如此。注意在本例的方法内部,
方法使用比输入参数小1的实参调用自身。

调用方法自身的机制和调用其他方法其实是完全一样的,都是为每一次方法调用把新的栈帧
压入栈顶。
例如,在下面的代码中,Count方法使用比输人参数小1的值调用自身,然后打印输人的参
数。随着递归越来越深,栈也越来越大。

