C 系列之值型別和引用型別

2022-02-12 07:44:11 字數 1716 閱讀 9587

這幾天一直在思考這章討論什麼, 在上一章討論string的時候牽涉到引用型別,那麼我們這一章討論討論一下,值型別和引用型別。

值型別和引用型別,它們的區別**於傳值方式。有人會認為值型別就存在棧上這是不一定的。詳細看下文。

有些人會說啊。。有垃圾**機制進行清理記憶體。。不需要去折騰那麼多吧 - -!。。。。。為了寫好**,避免面試問到。。還是勉為其難的討論討論吧。。。。。

棧,儲存不是物件成員的值資料型別,還存放著區域性變數,引數。

那麼他的工作原理是怎樣的呢?首先要知道,資料在棧上,是從高記憶體位置往低記憶體位置填充的,變數位址不會重複的。

假如有下面一段**:

從上面可以看見,b**塊是巢狀a**塊裡。由於**從上到下的執行順序,那麼變數a會比變數b先入棧;可是b**塊會比a**早結束,超出作用域之後,變數就會釋放,因此,變數b會比變數a先釋放。

由此可見,靈活性並不高,如果希望生命活得長久點?這個時候,堆的作用就體現出來。

堆,它的特性和棧有點相反,儲存的是物件成員型別,是從低記憶體位置往高記憶體位置填充的。當值型別的變數為型別成員的時候,是與物件存放在堆裡。

先說下工作原理,有這樣一段**。

class

program

}

首先,會在棧上分配乙個空間,存放引用h,它僅僅是乙個引用,不是物件。到第二句進行例項化物件,new 運算子是用來請求分配儲存空間的,clr會搜尋堆上足夠的位置,分配給物件,然後new會返回它所在堆上的位址給引用。因此在棧上存放著該引用指向堆上的物件的位址。

值型別的使用減少了堆的壓力,同時減少垃圾**的次數。引用型別卻彌補了生命週期的不足,增加了靈活性。 

值型別建立變數時是賦予預設值的,例如int預設值是0。而引用型別建立變數,預設是null。那麼,沒有物件的引用型別的變數使用時會報異常nullreferenceexception。

值型別的變數是以複製的方式賦值,執行一次逐字段的複製,而引用型別將物件在堆上的位址賦於新變數進行引用。 

下面有段**充分說明了引用型別和值型別的區別 :(借用clr c#的例子)

struct struct//

值型別class class //

引用型別

class

program

}

c1將位址複製給c2,也就是說c1和c2指向的是同乙個物件,因此c1和c2其中乙個修改了,另外的也會受影響。

s1將成員複製給s2,雖然s1和s2儲存了相同的值,但是他們記憶體位址都不相同,存的是屬於自己的值,因此s1和s2其實乙個修改了,也不會影響另外乙個。

寫到這裡也差不多了。其實說到引用型別和值型別,還說牽涉到裝箱和拆箱的,小弟對那塊還沒多深的了解,等以後再和大家**。

感冒了。。休息去。。。乙個多星期還沒好,今天貌似又嚴重了。。公司的流感太厲害了。。希望各位注意身體。。=。=。。。。。

C 之值型別和引用型別

值型別與引用型別是很基礎的知識,也有很多對此的介紹,如果想深入了解,張老師的部落格講解的很好,鏈結如下 我在這裡只是淺淺的介紹一下下 從概念上看,值型別直接儲存其值,而引用型別儲存對其值的引用。我們知道,c 中的每一種型別要麼是值型別,要麼是引用型別。所以每個物件要麼是值型別的例項,要麼是引用型別的...

C 值型別和引用型別

c 資料型別 值型別,引用型別 概念 值型別直接儲存其值,引用型別儲存對值的引用 這兩種型別儲存在記憶體的不同地方 值型別儲存在堆疊中,引用型別儲存在託管堆上。乙個引用型別的例子,如圖 上圖中,只有乙個user物件,u1和u2都指向包含該物件的記憶體位置 執行結果 在c 中,基本資料型別如bool和...

c 值型別和引用型別

今天我們來學習一下什麼是值型別和引用型別。1.值型別的值存在棧上,引用型別棧上存的是位址,值在堆上 2.將乙個值型別變數賦給另乙個值型別變數時,將複製包含的值。引用型別變數的賦值只複製對物件的引用,而不複製物件本身。3.裝箱是將值型別轉換為引用型別,拆箱是將引用型別轉換為值型別,利用裝箱和拆箱功能,...