C#基础篇-方法详细总结(涉及底层)

一:知识点流程

在这里插入图片描述

二:定义方法,调用方法,递归调用

1.定义方法:
①:方法是把一些相关的语句组织在一起,用来执行一个任务的语句块。
②:语法
定义方法
③例:

        public  static void exchange(int a,int b)
        {
            int exchange;
            exchange = a;
            a = b;
            b = exchange;
        }

访问权限
备注:访问权限是允许访问该类或该成员变量或该函数的范围,类的默认访问标识符是 internal,成员的默认访问标识符是 private。


2:调用方法
①:静态调用
②:非静态调用

    class Program
    {
        public static  int Add(int a,int b)
        {
            return a + b;
        }
        public int Sub(int a,int b)
        {
            return a - b;
        }
    }
    class test
    {
        static void Main(string[] args)
        {
             //静态调用:不需要实例化对象
            int sum =Program.Add(10, 20);
            Console.WriteLine($"10+20={sum}");
            //非静态调用
            Program pro = new Program();
            int sub= pro.Sub(20,10);
            Console.WriteLine($"20-10={sub}");
            Console.ReadLine();
        }
    }

运行结果:
在这里插入图片描述
③:递归调用(函数调函数,注意不要造成死循环)

  public static int factorial(int num)
        {
            /* 局部变量定义 */
            int result;

            if (num == 1||num==0)
            {
                return num;
            }
            else
            {
                result = factorial(num - 1) * num;
                return result;
            }
        }

        static void Main(string[] args)
        {
            Console.WriteLine($"0的阶乘:{factorial(0)}");
            Console.WriteLine($"1的阶乘:{factorial(1)}");
            Console.WriteLine($"10的阶乘:{factorial(10)}");
            Console.ReadLine();

        }

运行结果:
在这里插入图片描述


三:参数传递

1:按值传递(重点:传递的是值!)
①:例

       static void Main(string[] args)
        {
            int a = 100, b = 200;
            //按值传递参数
            exchange( a, b);
            Console.WriteLine("-----我是分割线---------");
            Console.WriteLine("a={0};b={1}",a,b);
            Console.ReadLine();
        }

        public static void exchange(int a, int b)
        {
            int exchange;
            exchange = a;
            a = b;
            b = exchange;
            Console.WriteLine("exchange={0}",exchange);
            Console.WriteLine("a={0}", a);
            Console.WriteLine("b={0}", b);
        }

运行结果:
运行结果
③:底层分析:

底层分析
//mov:数据传送指令
目的操作数:ecx,edx 源操作数:dword ptr [ebp-40h],dword ptr [ebp-44h]

 02DB4103  mov         ecx,dword ptr [ebp-40h]  
 //翻译:
 ecx=dword ptr [ebp-40h]=100;//exchange(a, b); a=100
 02DB4106  mov         edx,dword ptr [ebp-44h]  
 //翻译:
 edx=dword ptr [ebp-44h]//exchange(a, b); b=200

备注:mov指令只是做到了值的传递,拷贝复制过程,没有涉及到地址,所以这里的a=200 b=100也只是局限于"exchange(int a, int b)"这个函数(方法)内部,只在这个作用域下起作用。


2:按引用传递参数 ref(重点传递的是地址!)

①:例

        static void Main(string[] args)
        {
            int a = 100, b = 200;
            //按引用传递参数
            exchange(ref a,ref b);
            Console.WriteLine("a={0};b={1}",a,b);
            Console.ReadLine();
        }

        public static void exchange(ref int a, ref int b)
        {
            int exchange;
            exchange = a;
            a = b;
            b = exchange;
        }

②:运行结果:
运行结果
③:底层原理
groundfloor

这里采用的是lea指令,对于变量而言传递的是地址。(和mov指令相反)

016345A1  lea         ecx,[ebp-40h]  //ecx=ebp-40h
016345A4  lea         edx,[ebp-44h]  //edx=ebp-44h

④:注意
注意1:
在这里插入图片描述
注意2:传参必须赋值!
特点

备注:引用参数是一个对变量的内存位置的引用(lea指令)。当按引用传递参数时,与值参数不同的是,它不会为这些参数创建一个新的存储位置。引用参数表示与提供给方法的实际参数具有相同的内存位置。


3:输出类型 out

①:可以把输出参数看成数据返回参数
在这里插入图片描述
②:和ref相似处:
ref和out都是传递地址,底层操作基本一致。
在这里插入图片描述
在这里插入图片描述
必须以out一起传递。(调用时都需要输入相应的关键字)
在这里插入图片描述
③:和ref不同处
可以使用未赋值的局部变量
在这里插入图片描述
不能使用未赋值的out参数

在这里插入图片描述

④:例:

using System;

namespace CalculatorApplication
{
   class NumberManipulator
   {
      public void getValues(out int x, out int y )
      {
          Console.WriteLine("请输入第一个值: ");
          x = Convert.ToInt32(Console.ReadLine());
          Console.WriteLine("请输入第二个值: ");
          y = Convert.ToInt32(Console.ReadLine());
      }
   
      static void Main(string[] args)
      {
         NumberManipulator n = new NumberManipulator();
         /* 局部变量定义 */
         int a , b;
         
         /* 调用函数来获取值 */
         n.getValues(out a, out b);

         Console.WriteLine("在方法调用之后,a 的值: {0}", a);
         Console.WriteLine("在方法调用之后,b 的值: {0}", b);
         Console.ReadLine();
      }
   }
}

运行结果:
运行结果
备注:当需要从一个参数没有指定初始值的方法中返回值时,输出参数特别有用。


相关链接:汇编常用指令

发布了49 篇原创文章 · 获赞 17 · 访问量 4301

猜你喜欢

转载自blog.csdn.net/weixin_42753193/article/details/104871958