C 堆VS棧 值型別VS引用型別

2022-05-03 22:30:27 字數 2553 閱讀 4465

最近上連續出現了幾篇關於堆vs棧 值型別vs引用型別的文章。

乙個是關於c# 堆vs棧的,深入淺出,**清晰明了,鏈結如下

c#堆疊對比(part one)

c#堆疊對比(part two)

c#堆疊對比(part three)

c#堆疊對比(part four)

the truth about value types

你真的了解c#中的值和引用嗎?(上)

匹夫細說c#:不是「棧型別」的值型別,從生命週期聊儲存位置

下面是我的思考和總結,希望能與大家分享和討論。

最近和同事一起面試時也經常問這個問題,被面的同學很多回答為「值型別儲存在棧裡,引用型別儲存在堆裡」,首先我們先不去深究這個說法是否準確(上面的文章裡已經說的很清楚)。

值型別和引用型別的區別是儲存位置的不同嗎

eric lippert給出的答案----值型別和引用型別的區別在語義層面,與儲存位置無關。儲存位置是c#編譯執行時的分配,是實現細節。

或許c# compiler的未來版本中,值型別也可能不儲存在棧裡;

或者某乙個系統平台中並不存在堆和棧的概念。

結論「值型別和引用型別的區別,與儲存位置無關」。

eric lippert說 -值型別和引用型別的區別在語義層面。要怎麼理解?我們思考的視角應該是c#語言語義和使用上。

結論「值型別傳遞的是值(不同的例項,互不影響),引用型別傳遞的是引用(同乙個例項,互相影響)

如同一句廢話!那我們試著換幾種方式來描述(可能不準確

1. 值型別是私有的,是持有者自己的東西;引用型別是共享的,大家共有的東西。

2. 值型別是多例項的,每次傳遞都建立新例項;引用型別是單例項的,每次傳遞都是同乙個例項,如設計模式中的單例。

3. 值型別的生命週期和持有者相同;引用型別的生命週期和持有者不同。(有關生命週期的言論)

如何實現值型別和引用型別的儲存?

有兩種儲存方式可供選擇

直接儲存的優點是效能高,缺點是共享不方便。(棧或者堆上

間接儲存的優點是共享方便,缺點是多了一次跳轉,有效能損失。(堆上

我們要的關注哪些問題?效能,共享方式(生命週期)

值型別是不共享的,它的生命週期和持有者相同,所以可以直接儲存,如果間接儲存,會多一次跳轉,沒有意義的效能損失。

引用型別是共享的,它的生命週期和持有者不同,所以採用間接儲存,如果直接儲存,是很難實現共享和生命週期的不同。

結論值型別是直接儲存,引用型別是間接儲存。是基於實現的考量,不是值型別和引用型別的區別。

生命週期是從實現角度思考的推論,也不是值型別和引用型別的區別。

思考後發現,所有值型別都可以被引用型別所替代,那為什麼要有值型別呢?沒有得出理想的答案,推測有兩種可能

一 歷史傳承。

二 基於效能的考量。這個應該是實現級別的事情,為什麼被暴露在語言級別上?沒有辦法解決嗎?(對於值來說,引用型別多了一次跳轉;對於引用來說,值的傳遞多了一次深轉殖)

在工作中很少(幾乎沒有)使用struct,因為效能上的收益遠遠無法彌補維護成本的損失

(不能要求每個開發人員都很了解struct和class的不同,並在修改**時意識到使用的是struct而不是class)

值和引用型別的區別是語言和使用級別的

值型別傳遞的是值(不同的例項,互不影響),引用型別傳遞的是引用(同乙個例項,互相影響)

有關值型別和引用型別儲存在棧或者堆上的言論,是基於實現細節的思考,是當前的實現方式,不是值型別和引用型別的區別。

有關值型別和引用型別生命週期的言論,是基於實現細節的思考,是當前的實現方式,不是值型別和引用型別的區別。

值型別(struct)更多是效能上的收益,c#中定義的基礎值型別已經足夠,開發中盡量避免定義值型別(struct)

C 堆與棧 值型別 引用型別

先說c 中值型別和引用型別 概念 1.值型別 資料儲存在記憶體的堆疊中,從堆疊中可以快速地訪問這些資料,因此,值型別表示實際的資料。2.引用型別 表示指向儲存在記憶體堆中的資料的指標或引用 包括類 介面 陣列和字串 c 中定義的值型別包括原型別 sbyte byte short ushort int...

值型別何引用型別,堆和棧

本文主要是討論棧和堆的含義,也就是討論 c 的兩種類據型別 值型別和引用型別 雖然我們在.net中的框架類庫中,大多是引用型別,但是我們程式設計師用得最多的還是值型別。引用型別如 string,object,class等總是在從託管堆上分配的,c 中new操作符返回物件的記憶體位址 也就是指向物件資...

值型別和引用型別,棧和堆的含義

原文出自 本文主要是討論棧和堆的含義,也就是討論 c 的兩種類據型別 值型別和引用型別 雖然我們在.net中的框架類庫中,大多是引用型別,但是我們程式設計師用得最多的還是值型別。引用型別如 string,object,class等總是在從託管堆上分配的,c 中new操作符返回物件的記憶體位址 也就是...