zoukankan      html  css  js  c++  java
  • 理解C#中参数

    岁末了 正好有机会说说C#中的ref,Out与参数传递的关系。

    第一次写技术博客,写的不好,多提意见。

     ---------------------------------------------------------------------分割线--------------------------------------------------

    分割线上面是2014年提的笔,现在是2016年收的尾!

    没有准备我就随便写了!

    C#中数据类型分值类型和引用类型,值类型变量保存的变量的值、引用类型保存的是变量的地址

    C#中函数的参数都是按值类型传递的,除非使用了ref 或者out。

    先证明函数的参数是按值类型传递的

    看下面的例子

    public void f1(int a)

    {

    a=123;

    }

    int b=111;

    f1(b);

    console.write(b);//111

    上面调用函数f1时候过程是实参b给形参a赋值,a和b是两个互不影响的变量。这个比较容易理解。下面再看引用类型的案例

    public void f2(List<int> ll)
    {

    ll.add(2);

    }

    List<int> l=new List<int>();

    l.add(1);

    f2(l);

    console.write(l.count);//2

    如果参数是按值类型传递的那为什么会输出2呢?因为引用类型变量名称保存的是值的值。

    List<int> l=new List<int>();//这句话实际上在内存中开辟了2块存储空间,一个是l,另一块是l的值指向的地址

    当调用f2的时候实参l给形参ll赋值,按值类型赋值,l的值赋给ll,此时ll的值也是上面new出来的地址,此时实参l和形参ll都是指向的同一个内存空间,所以在f2中对ll操作的结果会影响到l。下面讲string类型的

    public void f3(string s)

    {

    s="def";

    }

    string str="abc";

    f3(str)

    console.write(str)//abc

    咦!为什么是abc?如果按照刚刚讲的应该输出def才对啊!原因是这样的 在C#中string类型是不可变的(为什么说string类型是不可变的类型?我理解的是string s="abc";实际上也是string s=new string(new char[]{'a','b','c'});含义是在内存总开辟了一块空间保存abc,然后把这块空间的地址赋给变量s。)

    这里的str 给s赋值,也是按照值类型进行赋值,赋值之后str和s同时指向abc,关键在于在函数f3中s="def";这一句话也就是s=new string(new char[]{'d','e','f'});解释在内存中开辟了一段空间存储def 然后把这段空间的地址赋给s。此时str 和s已经发生了质变,str还是原来的str,s已经不是原来的s了!

    下面代码可以查看变量的地址

       static void Main(string[] args)
            {
                unsafe
                {
                    string str = "abc";
                    fixed (char* p = str)
                    {
                        Console.WriteLine("字符串地址= 0x{0:x}", (int)p);

                    }
                    f3(str);
                    fixed (char* p = str)
                    {
                        Console.WriteLine("字符串地址= 0x{0:x}", (int)p);

                    }
                }
                string ss = new string("asdf");
                Console.ReadKey();
                
            }

            public static  void f3(string s)
            {
                unsafe
                {
                    fixed (char* p = s)
                    {
                        Console.WriteLine("参数赋值前字符串地址= 0x{0:x}", (int)p);

                    }
                    s = "def";
                    fixed (char* p = s)
                    {
                        Console.WriteLine("参数赋值后字符串地址= 0x{0:x}", (int)p);

                    }
                }
            }

    再来说说ref和out

    其实他们很简单理解ref 和out都是强制把参数以引用类型传递!具体可以自己写个例子自测。最后附图一张

  • 相关阅读:
    JAVA 优先获取外网Ip,再获取内网Ip
    session 关于localhost和本地IP地址 不共享问题
    读取properties的简单方法,使用@Configuration
    数组和工具类练习
    for循环练习题
    eclipse 的输入输出练习
    用eclispe练习常、变量数据类型之间的转换
    第一个java小程序
    Java基础理论(1)
    字符集
  • 原文地址:https://www.cnblogs.com/chouxiaoya/p/4279112.html
Copyright © 2011-2022 走看看