由堆棧所能想到的以及ref,out參數

由堆棧所能想到的??

提到堆棧區別,大部分首先想到的是,“值類型存儲在棧中,引用類型存儲在堆中,引用類型在棧上存儲指向堆的地址”這句話。說這個我先想說一下值類型和引用類型,以及值傳遞和引用傳遞,關於值類型有哪些,以及引用類型有哪些,這些可以自己去了解。

將一個值類型賦值給另一個值類型,是將值得本身全部賦值過去,簡言之,就是值類型的值傳遞傳遞的是值得本身,如下

    class Program
    {
        //值傳遞&引用傳遞

         static void Main(string[] args)
        {
            //值類型:int double char bool enum... 存儲值的
            //引用類型:string 數組 自定義類,集合 object.. 存儲對值的引用的(可以理解爲存儲值在堆中的數據地址)
            //這裏有篇博客說的很好:http://www.cnblogs.com/jiajiayuan/archive/2011/09/23/2185966.html
            unsafe
            {
                //值傳遞
                int n1 = 10;//地址:0x058***98
                int n2 = 20;//地址:0x058***94
                n1 = n2;
                int* adress_n1 = &n1;//使用C#指針需要將語句塊標記爲unsafe表示不安全上下文
                int* adress_n2 = &n2;
                Console.WriteLine(n1);
                Console.WriteLine(n2);
                Console.WriteLine((int)adress_n1);//輸出n1在棧上的地址
                Console.WriteLine((int)adress_n2);//輸出n2在堆棧上面的地址
                Console.ReadKey();
            }
        }
    }

值傳遞編輯圖示


flag:這裏待會將會和ref關鍵字有聯繫。

下面可以看看引用類型的引用傳遞又是怎麼一回事。

        //引用傳遞
        static void Main(string[] args)
        {
            Person p1 = new Person();
            p1.Name = "pc";
            Person p2 = new Person();
            p2.Name = "ppcc";
            p2 = p1;
            Console.WriteLine(p1.Name);
            Console.WriteLine(p2.Name);
            Console.ReadLine();
        }
    }

    public class Person
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }

引用傳遞編輯圖示


我們知道字符串也是引用類型,但是對於字符串由於字符串擁有不可變性,所以很特殊。

        static void Main(string[] args)
        {
            string s1 = "pc";//字符串引用類型,但是字符串擁有不可變性
            string s2 = s1;
            s2 = "ppcc";
            Console.WriteLine(s1);
            Console.WriteLine(s2);
            Console.ReadLine();
            //輸出結果
            //pc
            //ppcc
        }

ref參數

        static void Main(string[] args)
        {
            int a = 20;
            Test1(a);
            Console.WriteLine(a);//輸出是多少?是20
            Console.ReadLine();
        }

        public static void Test1(int a1)
        {
            a1 += 1;
        }
在Test1裏面a的值是21,但是這個方法由於沒有返回值,所以,最後輸出結果還是原值。那這個例子和ref參數就有關了,有資料說,ref參數可以將值類型的傳遞改成傳遞地址,通過對地址的操作改變值類型本身。

        static void Main(string[] args)
        {
            int a = 20;
            Test1(ref a);
            Console.WriteLine(a);//輸出是多少?是21
            Console.ReadLine();
        }

        public static void Test1(ref int a1)
        {
            a1 += 1;
        }

關於它和out參數的區別,記住一句話,因爲ref參數是從外部傳遞到函數裏面的,所以要求必須在函數外部進行賦值,而out參數因爲是從方法內部傳遞出去的,所以要求在方法內部必須對其進行有值操作。

out參數

        static void Main(string[] args)
        {
            int a = 20;
            int b;//使用out參數的時候 這裏不用賦值,因爲值是從一個函數裏面傳遞出來的
            //Test1(ref a);
            Test2(out b);
            Console.WriteLine(b);//輸出是多少?是-1
            Console.ReadLine();
        }

        //public static void Test1(ref int a1)
        //{
        //    a1 += 1;
        //}

        public static void Test2(out int b)
        {
            b = 3;//在函數內部必須賦值
            b -= 1;
        }

留下的思考就是,out參數是否也是通過改變參數的傳遞方式?鏈接一個爲什麼C#中屬性不可以使用ref,out參數

http://book.51cto.com/art/200910/158498.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章