從棧和堆中來看值傳遞和引用傳遞

2021-07-26 20:10:48 字數 2655 閱讀 2720

棧是乙個記憶體陣列,是乙個lifo(last-in first-out,後進先出)的資料結構。

棧儲存幾種型別的資料:

某些型別變數的值;

程式當前的執行環境;

傳遞給方法的引數。

棧有如下幾個特徵:

資料只能從棧的頂端插入和刪除。

把資料放到棧頂稱為入棧(push)。

從棧頂刪除資料稱為出棧(pop)。

棧是在編譯期,由編譯器分配好記憶體空間。

堆是一塊記憶體區域,在堆中可以分配大塊的記憶體用於儲存某型別的資料物件。

與棧不同,堆裡的記憶體能夠以任意順序存入和刪除。

堆是在執行期,根據程式運**況動態分配記憶體空間。

c#資料型別分為兩種:值型別和引用型別,這兩種型別的物件在記憶體中的儲存方式不同。

值型別:只需要一段單獨的記憶體,用於儲存實際的資料。

引用型別:需要兩段記憶體。

第一段儲存實際的資料,它總是位於堆中。

第二段是乙個引用,指向資料在堆中的存放位置。

一般情況下,對於值型別,資料存放在棧裡。對於引用型別,引用存放在棧裡,實際資料存放在堆裡。如圖所示:

當然,上面是一般情況,值型別資料或引用型別的引用部分也會存放在堆中。

比如,當乙個值型別或乙個引用型別是另乙個引用型別物件的資料時,便會存放在堆中。

c#中的值型別和引用型別如圖所示:

值引數:通過將實參的值複製到形參的方式把資料傳遞給方法。方法被呼叫時,系統在棧中為形參分配空間,然後將實參的值複製給形參。

引用引數:在引數前面加 ref 或 out 修飾符 ,實參必須是變數。

ref 和 out 的區別:ref引數傳入方法之前必須初始化;out引數不需要,但out引數在方法返回時必需賦值。

using system;

namespace test

",val);

}static void mymethod(int ***)

",***);}}

}

結果如圖所示:

分析如圖所示:

}結果如圖所示:

分析如圖所示:

寫了兩個例子,注意在方法內部形參p的不同之處!

示例1:

using system;

namespace test

",p1.name);

}static void mymethod(person p)

",p.name);}}

class person

}

結果如圖所示:

分析如圖所示:

示例2:

using system;

namespace test

",p1.name);

}static void mymethod(person p)

;console.writeline("p.name的值為:",p.name);}}

class person

}

結果如圖所示:

分析如圖所示:

;console.writeline("p.name的值為:",p.name);}}

class person

}結果如圖所示:

分析如圖所示:

作為值引數(即值傳遞)時:傳遞的是棧中的資料。

值傳遞和引用傳遞

幾乎每種語言都有值傳遞和引用傳遞.下面是我的一些曲解,只講現象,不涉及到任何的原理,主要是鬧著玩的.a 新交了個女朋友b.有一天他女朋友b看見a在吃冰激凌,b想吃,但是a是個 座有點小潔癖,不想讓b吃,於是給b買了個新的冰激凌說你吃這個吧,別碰我嘴裡這個.這就是值傳遞.a和b的值沒有任何關係,他們一...

值傳遞和引用傳遞

1.什麼是值傳遞和引用傳遞 值傳遞 方法呼叫時,實際引數的值copy乙份傳遞給形式引數,此時,有兩個相等的數值分別儲存於不同的記憶體位址上,因此,後面的方法中都是對形參位址上的數值進行修改。引用傳遞 方法呼叫時,實際引數的值 也就是位址 copy乙份傳遞給形式引數,此時,形參和實參的引用都指向同一儲...

值傳遞和引用傳遞

定義 通過建立乙個實際引數的副本,再傳遞給方法的形式引數,在main自身並不會被使用。這個在我們第一次使用編寫交換數的方法時,基本都會遇見,當我呼叫a,b兩個變數時,通過交換方法交換他們的位置,但是沒用,這就是值傳遞,乙個坑 public class switchnum switchnum a,b ...