【C#语言入门】07. 方法的定义、调用与调试(下)

本文介绍了C#语言中构造器的声明与调用,包括实例构造器、内存原理,以及方法的重载概念和示例。此外,还详细讲解了如何进行方法的调试,涉及断点设置、CallStack、步进操作和观察局部变量。
摘要由CSDN通过智能技术生成

【C#语言入门】07. 方法的定义、调用与调试(下)

三、构造器

  • 构造器(constructor)是类型的成员之一
  • 狭义的构造器指的是“实例构造器“(instance constructor)
  • 如何调用构造器
  • 声明构造器
  • 构造器的内存原理

1. 实例构造器,声明与调用

 internal class Program
 {
     static void Main(string[] args)
     {
         Student stu = new Student();
         Console.WriteLine(stu.ID);
         Console.WriteLine(stu.Name);
         Console.WriteLine("======================")
         Student stu2 = new Student(2, "Mr.Bu");
         Console.WriteLine(stu2.ID);
         Console.WriteLine(stu2.Name);
     }

 }
 class Student
 {
     public Student(int stuid, string stuname)
     {
         this.ID = stuid;
         this.Name = stuname;
     }
     public Student()
     {
         this.ID = 0;
         this.Name = "No Name";
     }
     public int ID;
     public string Name;
 }

一个类如果没有自定义构造器的话他也是有默认的构造器的,而且不显示。自定义的构造器必定是有public且方法名是与类名一致。一个类也可以有多个构造器。(快速写构造器——输入“ctor”——两下Tab键)

2. 构造器的内存原理

new 操作产生实例后,系统会去看你这个实例要占据多少内存空间,如上述例子Student中含有一个int和一个string,32bit+32bit一共占8字节,而构造器的作用就是把划分的8字节内存空间进行具体分割以及初始化。

四、方法的重载(Overload)

  • 调用重载方法的示例
  • 声明带有重载的方法
    • 方法签名(method signature)由方法的名称、类型、形参的个数和它的每一个形参(按从左到右的顺序)的类型和种类(值、引用或者输出)组成。方法签名不包括返回类型。
    • 实例构造函数签名由它的每一个形参(按从左到右的顺序)的类型和种类(值、引用、或者输出)组成。
    • 重载决策(到底调用哪一个重载):用于在给定了参数列表和一组候选函数成员的情况下,选择一个最佳函数成员来实施调用。

1. 重载的示例

Console.WriteLine("Hello");
Console.WriteLine(100);
Console.WriteLine(200D);
Console.WriteLine(3000L);

都是Console.WriteLine方法,但是他们的形参类型各不相同。

public int Add(int a, int b)
{
  return a + b;
}
public int Add(int a, int b, int c)
{
  return a + b + c;
}
public int Add(double a, double b)
{
  return a + b;
}

都是Add方法,但是他们的形参类型/数量各不相同。

五、如何对方法进行debug

  • 设置断点(breakpoint)
  • 观察方法调用时的call stack
  • Step-in, Step-over, Step-out
  • 观察局部变量的值与变化

1. 目的

  1. 为了找到BUG发生的地方
  2. 为了动态的了解我们的程序是怎么运行的

2. 设置断点

设置断点后,在调试模式下程序会停在设置断点的那一句代码,供程序员观察。设置断点的方法是在语句行的最左边点一下,会出现一个红圈。

3. Call Stack

会出现被调用的函数以及调用它的函数,甚至是调用调用它的函数,直到找完找到最上层的调用函数。

4. Step-in, Step-over, Step-out

  • Step-into:最仔细的debug方法,是会进入到调用的函数中一步一步走。
  • Step-over:如果调用了一个方法,它是会直接跳出调用的函数的最终值,在走下去。
  • Step-out:直接回到调用当前这个方法的方法中去,相当于在CallStack上调用当前方法的方法上又设了一个断点。

5. 观察局部变量

需要用到locals面板,他会显示用到的本地变量,同时也会标注出变化了的变量。

六、方法的调用与栈

  • 方法调用时栈内存的分配(对stack frame的内存分析)

1. stack frame

表示一个方法在被调用时,它在内存空间中的布局。

2. 分配

栈内存是从高字节位到低字节位存储,全满了就会overflow。

class Progarm
{
    static void main(string[] args)
    {
        double result = Calculator.GetConsVolume(100, 100)
    }
}

class Calculator
{
    public static double GetCircleArea(double r)
    {
        return Math.PI * r * r;
    }
    public static double GetCylinderVolume(double r, double h)
    {
        return GetCircleArea(r) * h;
    }
    public static double GetConeVolume(double r, double h)
    {
        return GetCylinderVolume(r, h) /3.0;
    }
}

main函数是主调者(Caller),Calculator.GetConsVolume是被调者(Callee),方法的两个变量在C#中是归主调者也就是这里面的main函数管理内存空间的,也就是说谁调用,谁负责将变量从左到右压到栈内存中去。

函数的返回值比较特殊,是存放在CPU的寄存器中的。

一个函数在返回(return)之后,他会释放掉那些没用的内存。比如说主调函数调用的参数。

所以overflow就是因为一直在调用函数但是没有返回,导致栈存爆了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值