zoukankan      html  css  js  c++  java
  • (11)C#值类型和引用类型,堆和栈,ref和out,装箱和拆箱

    一、值类型和引用类型定义

    以内存中的存在方式可以把变量分成两大类型,值类型和引用类型。

    值类型:系统只占用一块内存,数据直接存储在内存里。

    引用类型:系统占用两块内存,一块存放地址,另一块存放实际数据,并且前一块这个地址就是后一块在内存中所在的位置。

    对引用类型举个例子:把两块白纸(白纸1、白纸2)比喻成两块个内存。白纸2上画了一个仓库,仓库里有电视、冰箱、花瓶等各式各样的东西,而白纸1上写的只有一行字上面记录了这个仓库的位置(天津市河区西红孩儿路123号)

    二、变量的划分

    值类型:

    内置值类型:说的应该是所有的基本数据类型吧。

    用户定义的值类型:结构类型

    引用类型:字符串、数组、对象等。 上面的图还不太懂等学完以后再回来补充

    三、为什么要分成值类型和引用类型?

      原因1. 值类型直接存储其值,变量本身就包含了其实例数据,而引用类型保存的只是实例数据的内存引用。 因此,一个值类型变量就永远不会影响到其他的值类型变量,而两个引用类型变量则很有可能指向同一地址,从而发生相互影响。

                int a = 5;
                int b;
                b = a;
                Console.WriteLine(a);//a=5
                Console.WriteLine(b);//b=6
                a++;
                Console.WriteLine(a);//a=6
                Console.WriteLine(b);//b=5

    值类型a的变化并没有影响b的变量

                int[] a = {5};//数组中只有一个元素
                int[] b = a;
             Console.WriteLine(a[0]);//结果是5
             Console.WriteLine(b[0]);//结果是5
             a[0] = 6;
             Console.WriteLine(a[0]);//结果是6
             Console.WriteLine(b[0]);//结果是6

    引用类型a的值变了,b也跟着发生了改变

    有个特殊的变量 string类型

    我们用和上面同样的方法做实验

                String a = "me";
                String b = a;
                Console.WriteLine(a);//me
                Console.WriteLine(b);//me
                a = "meeeee";//重新a赋值
               Console.WriteLine(a);//meeeee
                Console.WriteLine(b);//me

    结果得到的a和b的值不一样,按刚才的道理来讲字符串时引用类型所以b的值应该和a的值相等,但是string类型有些特殊。

    string一个特点就是它具有恒定不变性,我们将不能以任何方式对这个string进行修改使之变长、变短、改变格式。之所以在给字符串变量重新赋值时发生了改变(a = "meeeee";)详见(8)C#字符串、异常

      原因2. 从内存分配上来看,值类型通常分配栈上,作用域结束时,所占空间自行释放,效率高, 无需进行地址转换,而引用类型通常分配在堆上,由垃圾回收器来控制其回收,需要进行地址转换,效率降低,这也正是c#需要定义两种数据类型的原因之一。

    四、堆和栈

    参考http://www.jb51.net/article/55306.htm

    五、ref和out参数

    形参与实参

    在方法的()里的参数一般叫做形参,而传给这个形参的实际值就叫做实参。形参和实参一般是在方法中才有的。

    static void method (int a)
    {
    a++;
    }
    static void Main()
    {
    int b=3;
    method(b);
    Console.WriteLine(b);//b的值没有改变,仍然是3.
    }

    通常情况下在方法的()里定义的参数a修改后不会影响b的值。

    但是有一种方法就是在参数前加ref这个关键字

    static void method (ref int a)//ref
    {
    a++;
    }
    static void Main()
    {
    int b=3;
    method( ref b);//ref
    Console.WriteLine(b);//b的值是4
    }

     out和ref的功能一样,只有在一点上有区别,

    ref定义的参数和普通参数一样,传到参数的变量必须是一个已经初始化了的变量.

    out不同,使用它的目的是,传来的是没有被初始化的变量,初始化要在方法体里进行时。(方法体力必须初始化变量,不然会报错)

    static void method (out int a)//
    {
    a=6;
    a++;
    }
    static void Main()
    {
    int b;
    method( out b);//
    Console.WriteLine(b);//b的值是7
    }

    六、装箱和拆箱

     参考http://www.cnblogs.com/huashanlin/archive/2007/05/16/749359.html

    装箱:值类型转换成引用类型

      具有子父类关系才能够装箱。

    拆箱:把引用类型转换成值类型

      装箱和拆箱必须是相同类型

    如何判断是否装箱?

    为什么使用装箱拆箱?

    效率问题

    using System.Collections;
    using System.Diagnostics;

                ArrayList arr = new ArrayList();
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 50000000; i++)
                {
                    arr.Add(i);
                }
                watch.Stop();
                Console.WriteLine(watch.ElapsedMilliseconds);//统计毫秒
                Console.ReadLine();

                List<int> list = new List<int>();
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 50000000; i++)
                {
                    list.Add(i);
                }
                watch.Stop();
                Console.WriteLine(watch.ElapsedMilliseconds);//统计毫秒
                Console.ReadLine();

     

  • 相关阅读:
    Program C--二分
    Program A-归并排序
    Program E-- CodeForces 18C
    Program B--CodeForces 492B
    2015 HUAS Provincial Select Contest #1 C
    2015 HUAS Provincial Select Contest #1 B
    2015 HUAS Provincial Select Contest #1 A
    CSU 1111.三家人。第三次选拔赛D题:整理花园酬劳分配问题
    将10进制整数转换成16进制整数输出
    -UVa10935题:Trowing cards away1解答及简单分析
  • 原文地址:https://www.cnblogs.com/buchizaodian/p/5611015.html
Copyright © 2011-2022 走看看