C# 练习03

1.静态变量和静态函数

  静态函数和静态变量只能通过类名来调用,不能通过实例名来调用

  静态函数里调用其他函数,该函数也应该是静态的

 对于静态函数和静态变量来说,不同实例里面,其是相同的,共享一个

static void Main(string[] args)
        {
            Console.WriteLine(Sample.bStatic);
            Sample s = new Sample() ;
            Console.WriteLine("Frist Time");
            Console.WriteLine(Sample.bStatic);
            s.a++;//只能调用非静态
            //Sample.bStatic++;//静态只能通过类名调用,不能通过实例来调用,所有实例共享一个静态
          //  Sample.StaticSample();
           // Console.WriteLine(Sample.bStatic);
            //Console.WriteLine(Sample.bStatic++);//先使用,再加一
            //Console.WriteLine(Sample.bStatic);
            Sample s1 = new Sample();
            Console.WriteLine("Second Time");
            Console.WriteLine(Sample.bStatic);

            Sample s2 = new Sample();
            Console.WriteLine("Third Time");
            Console.WriteLine(Sample.bStatic);


        }
    }

    class Sample
    {
        public int a = 0;
        public static int bStatic=0;
        public static void StaticSample()
        {
            Console.WriteLine("This is static method.");
        }

        public Sample() //在内部可以直接调用静态变量
        {
            bStatic++;//没创建一个实例就加1  
        }

2.值类型的值传递和引用传递

值传递在不同函数中,虽然变量命名可能相同,但是会分配不同的空间,只是会拷贝一份给函数当作实参,所以在不同函数中,其值没有办法传递;

引用传递是,不会为方法参数列表里的参数再分配空间;

引用类型:变量名字里储存的是索引(句柄)

        static void Main(string[] args)
        {
            int a = 99;
            int b = 10;
            Console.WriteLine("原始值");
            Console.WriteLine("a={0}&&b={1}", a, b);
            Swap1(a, b);
            Console.WriteLine("使用Swap1");
            Console.WriteLine("a={0}&&b={1}", a, b);
            Swap2(ref a, ref b);
            Console.WriteLine("使用Swap2");
            Console.WriteLine("a={0}&&b={1}", a, b);

        }

        static void Swap1(int a,int b)//值传递,为参数列表重新分配空间
        {
            int temp = a;
            a = b;
            b = temp;
        }

        static void Swap2(ref int a,ref int b) //引用传递,不为参数列表分配空间
        {
            int temp = a;
            a = b;
            b = temp;
        }

3.引用类型的参数传递

引用类型是指名字中存储的是句柄,而不是数据。以数组为参数,就是一种引用类型的值传递

以数组为参数的值传递,但其传递的是位置信息,所以也可以直接在原空间中改变数据

引用传递  ref a 表示a是标记着内存一块区域的标记,调用时,不会拷贝一份给函数当作实参,调用函数中使用的新的标记就是原来的标记,共用一个标记

对于引用参数来说,无论是拷贝了一份标记,还是两个标记就是同一个,其能起到的作用是一样的,所以其值传递和引用传递起到的效果是一样的,在调用结束后,其原函数中的值都会发生改变

但是在引用传递中,如果在函数中重新分配一个空间,让标记值向新的空间,函数结束,标记销毁,无法指回原来的空间,还留在新空间;在值传递中,由于标记是拷贝的,虽然会重新分配空间让标记指向新空间,但是函数结束后,还是会指向原来的空间。

 static void Main(string[] args)
        {
            int[] a = { 1, 2, 3 };

            Console.WriteLine("初始值");
            foreach (int i in a )
                Console.Write("{0}  ", i);

            Console.WriteLine("*****");

            //Console.WriteLine("调用Add1");
            //Add1(a);
            //foreach (int i in a)
            //    Console.Write("{0}  ", i);
            //Console.WriteLine("*****");

            Console.WriteLine("调用Add2");
            Add2(ref a);
            foreach (int i in a)
                Console.Write("{0}  ", i);
            Console.WriteLine("*****");

            Console.WriteLine("调用Add1");
            Add1(a);
            foreach (int i in a)
                Console.Write("{0}  ", i);
            Console.WriteLine("*****");

            //Console.WriteLine("调用Add3");
            //Add3(ref a);   //a是标记着内存一块区域的标记
            //foreach (int i in a)
            //    Console.Write("{0}  ", i);
            //Console.WriteLine("*****");

            //Console.WriteLine("调用Add4");
            //Add4(a);
            //foreach (int i in a)
            //    Console.Write("{0}  ", i);
            //Console.WriteLine("*****");
        }

        static void Add1(int []a)// 传递句柄,不用重新分配空间,调用结束后,主函数中的值已经被改变    //值传递
        {
            for (int i=0;i <a.Length;i++)    //传递位置信息
            {
                a[i]++;
            }
        }

        static void Add2(ref int[] a) //传递句柄,不用重新分配空间,调用结束后,主函数中的值已经被改变,和1一样     //引用传递
        {
            for (int i = 0; i < a.Length; i++)
            {
                a[i]++;
            }
        }

        static void Add3(ref int[] a)//重新分配,但是不会被销毁,主函数中a的值会发生改变         //引用传递    和主函数中公用一个空间
        {
            a=new int[4]  { 10, 11, 12 ,13};       //重新分配一个空间后,指向新的空间,但是函数运行结束后,无法指向原来的空间,丢失
            for (int i = 0; i < a.Length; i++)
            {
                a[i]++;
            }
        }

        static void Add4(int[] a) //重新分配空间,但是调用完后会被销毁,主函数中a的值任然不变      //值传递  将主函数中的a拷贝一份传递过来, 
        {
            a = new int[4] { 10, 11, 12, 13 };       //重新分配一个空间后,,指向新的空间,但是函数运行结束后,标记销毁,又指回原来的空间
            for (int i = 0; i < a.Length; i++)
            {
                a[i]++;
            }
        }
    }

4.可选参数和命名参数、变长参数

        static void Main(string[] args)
        {
            int a = 1;
            double b = 2;
            int c = 3;
            char h = 'b';
            Method(a, b, c, h);//可以给可选参数赋值
            Method(a, b, c);//也可以不赋值,就使用默认值
            Method(a, b, d: h);//命名参数:参数d的值使用之前定义的h的值   其中C是缺省的,使用默认值
            Method(a, b, c: 10);
            Console.WriteLine(Average(1));
            Console.WriteLine(Average(1, 2, 3, 4));
        }

        static void Method(int a,double b,int c=1,char d='R')//其中d 为可选参数,其默认值为R 一个函数的可选参数要一起放在最后
        {
            a = a + 1;
            b = a + 1;
        }

        static double Average(params int []a)//参数传递过来的数量可能是不定的,存储在数组里 其数据类型应该是一样的
        {
            int b = a.GetLength(0); //参数列表只能有一个不定长参数,可以加入定长参数
            double sum = 0;
            foreach (int k in a)
                sum += k;
            return sum / b;
        }

5.方法的重载

        //方法重载:方法名字一样,但是:参数数量不同
        //参数数量相同,但参数类型不同
        //参数数量和类型相同但是出现顺序不同
        //函数返回值类型不能作为重载的依据

        static void Main(string[] args)
        {
            double s = TriangleArea(3, 4, 5);
            double s2 = TriangleArea(3d, 4d, 5d);

        }

        //方法重载:方法名字一样,但是:参数数量不同
        //参数数量相同,但参数类型不同
        //参数数量和类型相同但是出现顺序不同
        //函数返回值类型不能作为重载的依据
        static double TriangleArea(double a,double b,double c)
        {
            Console.WriteLine("1");
            double s = (a + b + c) / 2;
            return Math.Sqrt(s * (s - a) * (s - b) * (s - c));
        }

        static double TriangleArea(double a, double h)
        {
            Console.WriteLine("2");
            return (a * h) / 2;
        }
        static double TriangleArea(int a, int b, double theta)
        {
            Console.WriteLine("3");
            return (a * b * Math.Sin(theta)) / 2;
        }

6.递归

程序中函数调用自己 每次规模减小 到最后又确定值

递归求阶乘:

 static void Main(string[] args)
        {
            Console.WriteLine(Fac(5));
            
        }
        static int Fac(int n)
            //递归求阶乘 程序中函数调用自己 每次规模减小 到最后又确定值
        {
            if (n == 0)
                return 1;
            else
                return n * Fac(n - 1);
        }

递归求汉诺塔:

static void Main(string[] args)
        {
            Hanmethod(5, 'A', 'B', 'C');
            Console.WriteLine(count);
        }
        static int count = 0;
        static void Move(char a,char c)
        {
            Console.WriteLine("From{0} to {1}", a, c);
            count++;
        }

        static void Hanmethod(int n,char a,char b,char c)
        {
            if (n == 1)
                Move(a, c);
            else
            {
                Hanmethod(n - 1, a, c, b);
                Move(a, c);
                Hanmethod(n - 1, b, a, c);
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值