zoukankan      html  css  js  c++  java
  • 只说ref

         先贴一段代码:

    class Program
    {
    static void Main(string[] args)
    {
    string ss = "asdf";
    operate(ss);
    Console.WriteLine(ss);
    Console.Read();
    }
    public static void operate(string aa)
    {
    aa = "sdf";
    Console.WriteLine(aa);
    }
    }


    输出是:

     sdf

    asdf

          先解释这个东西,在.net中值类型是存放在堆栈中的,引用类型分为两部分存储,一部分是指针存储在堆栈中,另外一部分是类型的实例存储的堆中.

          然后在说下

    string ss = "asdf";

          这一句代码发生了什么,首先.net在栈中分配了一个string类型的指针所需要的地址,它没有指向任何东西.然后.net在堆中查找有没有"asdf"这个string的实例,如果没有它就要新建立一个string实例为asdf然后把此实例的地址赋给刚才在栈中分配的那个指针,这就是等号的作用.

          然后我们在看operate(ss);这一句代码发生了什么.这个地方传递过来的是堆里面asdf的地址,然后.net又在栈上分配了一个string类型的指针所需要的地址,这一块地址就叫aa,但是呢这个aa中是有值的它的值就是刚才我们给asdf分配在堆上的内存区域的值.

          接着 aa = "sdf";由于已经给aa在栈上分配了内存区域,所以直接在堆上找有没有sdf这个实例,没有! 好重新拿出一块来存放sdf,然后把这块的内存地址放到刚才给aa分配的地址里面.

    后面的两个输出就简单了,只要分别输出栈里指针所指向的堆里面的值就可以了.

    以上是没有加ref的过程.

          另外一段代码:

     class Program
    {
    static void Main(string[] args)
    {
    string ss = "asdf";
    operate(ref ss);
    Console.WriteLine(ss);
    Console.Read();
    }
    public static void operate(ref string aa)
    {
    aa = "sdf";
    Console.WriteLine(aa);
    }
    }

    输出两行 sdf

          第一句赋值语句不解释了,跟第一种一样.现在来看第二句operate(ref ss);

          多了一个ref那传递过来的东西就不一样了,这里传递过来的是ss所在内存的地址,然后aa = "sdf";的时候还是要在堆上找有没有sdf这个实例,没有的话重新创建,分配堆地址.

    这个地方就是不一样的了,.net将这个分配好的地址编号,赋值给了ss所在的栈地址,而没有将此地址赋值给aa所在的栈地址.所以我们从方法返回后ss所指向的堆地址改变了.所以它的值也改变了

         

  • 相关阅读:
    tcp流协议产生的粘包问题和解决方案
    使用fork并发处理多个client的请求和对等通信p2p
    最简单的回射客户/服务器程序、time_wait 状态
    C/S程序的一般流程和基本socket函数
    socket概述和字节序、地址转换函数
    IP数据报格式和IP地址路由
    利用ARP和ICMP协议解释ping命令
    TCP/IP协议栈与数据报封装
    从汇编角度来理解linux下多层函数调用堆栈运行状态
    read/write函数与(非)阻塞I/O的概念
  • 原文地址:https://www.cnblogs.com/glorysword/p/2314988.html
Copyright © 2011-2022 走看看