c為什麼要有兩種資料型別(值型別和引用型別)

2022-12-16 15:21:04 字數 6124 閱讀 9010

1樓:匿名使用者

如果您這麼問

那麼我就假設您明白這兩個的區別

為什麼要有.我就大致解釋一下

值型別直接儲存其值,變數本身就包含了其例項資料,而引用型別儲存的只是例項資料的記憶體引用。因此,一個值型別變數就永遠不會影響到其他的值型別變數,而兩個引用型別變數則很有可能指向同一地址,從而發生相互影響。

例如您現在要做一件事情.他永遠都用的是一個變數..但是他們的類不同.使用地點也不同(也就是不能直接在呼叫處訪問到定義處)

那麼使用時候就是引用型別最方便

另外由於引用型別是指定記憶體地址.那麼程式也會很省記憶體.

你想想.你的軟體有10000個model(例如示例池,系統記憶體例項快取池等)

那麼如果你要使用它時候他居然是值型別.你如果要改變結果是穿引數時候直接new了一個.新的記憶體儲存.

這時候就是引用型別

值型別:

還是上面的快取池

如果你此時快取的是一些常用的定值.例如一些系統級的數字.引數

這時你只是臨時改變..

如果你是引用型別.那麼你就等於隱式的把系統改了.這就不合適了

所以用值型別.

2樓:空雪夢見

如果你學過c++,那麼事情就簡單了。

引用型別相當於指標變數,值型別相當於普通變數

在c#的資料型別中,什麼屬於值型別,什麼屬於引用型別

c#什麼是值型別什麼是引用型別

3樓:匿名使用者

1***、c#中有兩種型別:

值型別和引用型別:

值型別的變數直接包含他們的資料,而引用型別的變數儲存

引用型別儲存對他們的資料的引用,後者稱為物件:

簡單說:值型別直接儲存其值,引用型別儲存對值得引用.引用型別分為引用和引用的物件。

2***、

值型別:簡單型別、列舉、結構

引用型別: 類型別、介面型別、陣列型別和委託型別

3***、值型別與引用型別的記憶體儲存

單純的說值型別儲存在棧上,引用型別儲存在託管堆上是不對的。

4***、區別:

1、託管堆: 同步塊和方法表, x,y,託管堆上的需要gc來**

執行緒堆疊: 沒有同步塊和方法表

2、值型別賦值是重新建立一個副本

而引用型別的賦值是共享同一塊記憶體(副本),是指向同一塊記憶體(引用型別的名字相當於指向操作)。只是複製引用而不復制被引用識別的物件。(「引用」和「引用的物件」)

3、值型別與引用型別的不同之處就在於值型別的變數直接包括他們的資料,而引用型別的變數把references儲存到他們的資料庫(objects)中。

4、所有的值型別從object中繼承來的。任何型別都不能由值型別派生而來,因此,值型別是封閉式的。

5***什麼時候使用值型別

1)當型別是一個十分簡單的型別,其中沒有成員會修改型別的任何例項欄位

2)型別不需要從其他任何型別繼承

3)型別不會派生出其他任何型別

4)型別的例項較小

5)型別不作為方法引數傳遞,也不作為方法的返回型別使用

6)引用型別可以包含null值,值型別不能(可空型別功能允許將null賦給值型別);

6***什麼時候用ref和out

ref:值型別在傳遞希望成為引用的時候,ref就是告訴傳遞的時候不是拷貝,而是同一個副本。

out:不需要給變數賦初值,使用out也沒必要在外面賦初值,是在內部賦「初值」,out傳遞值是理解成沒有初始化的。

7***深度分析值型別和引用型別(記憶體中的部署)

例子:objectreference r = new object();

關鍵字new在託管堆上分配記憶體空間,並返回一個該記憶體空間的地址。左邊的reference位於棧上,是一個引用,儲存著一個記憶體地址;而這個地址指向的記憶體(位於託管堆上)裡儲存著其內容。

規律:1)引用型別部署在託管堆上

2)值型別總是分配在它宣告的地方:作為欄位時,跟隨其所屬的例項儲存。作為區域性變數時,儲存在棧上。

總結: 引用型別在棧上儲存一個引用,其實際的儲存位置位於託管堆。

8***裝箱與拆箱操作

1) 裝箱操作

裝箱(box)就是將值型別轉換為引用型別的過程。而相反的過程就叫拆箱(unbox)。

裝箱時發生了什麼?

(1)在堆上分配記憶體。因為值型別最終有一個物件代表,所有堆上分配的記憶體量必須是值型別的大小加上容納此物件及其內部結構(比如虛擬方法表)所需的記憶體量。

(2)值型別的值被複制到新近分配的記憶體中

(3)新近分配的物件地址被放到堆疊上,現在它指向一個引用型別。

2)拆箱操作

注:被裝過箱的物件才能被拆箱。

在裝箱的時候,並不需要顯示型別轉換.但在拆箱時需要型別轉換.這是因為在拆箱時物件可以被轉換為任意型別.

注意:裝箱操作可以隱式進行,但拆箱操作必須顯示。

首先,檢查這個物件例項,看它是否為給定值型別的裝箱值。

然後,把這個例項的值拷貝給值型別的變數。

要儘量減少裝箱與拆箱操作

9***問題

1)c#中null和""的區別

string是引用型別:

string str= null 沒有建立記憶體空間,str中存放的是空引用指標.

string str="" str中存放的是指向堆中的指標。有指向

簡單地說:

string str ="";

給你一張白紙;

string str = null;

連白紙也沒有。

string.empty就相當於"" 一般用於字串的初始化

判定為空字串的幾種寫法,按照效能從高到低的順序是:

s.length == 0 優於 s == string.empty 優於 s == ""

2)c#裡面的垃圾**

gc(垃圾**)**的都是可託管**,也就是託管堆中的**

一般定義一個引用變數,它肯定會在堆上面佔用一塊空間,棧上有個地址指向這個儲存位置,只有黨gc發現堆上這個資源在棧上沒有地址指向它的時候才把這塊記憶體**。

非託管資源gc是不會自動**的,例如資料庫連結,檔案等。

2 c#有哪些資料型別, 值型別 和應用型別的最大區別是什麼?

4樓:匿名使用者

一般來說是有二種資料型別的。1:值型別2:

引用型別,但指標型別也是c#中的一種資料型別。一般來說人們都是說有前面兩種型別,後者時常被遺忘。從記憶體來說的話它們兩者最大的區別是在於,值型別是在棧中儲存的,而引用型別它的引用則是放在棧中而資料則是放在堆中儲存的。

5樓:匿名使用者

c#中 資料型別分兩種 值型別和引用型別

值型別包括 基本資料型別 結構 列舉 等引用型別包括 類和介面等

區別是值型別的變數直接包含自身變數 將一個值型別變數賦給另一個值型別變數時 將複製包含的值

引用型別變數賦值 只複製物件的引用 而不復制物件本身

6樓:匿名使用者

研究下類和結構的區別

j**a中基本資料型別和引用資料型別有哪些

j**a中基本資料型別和引用資料型別各有什麼特點?

7樓:釋玥於翠梅

1、在記憶體中的儲存方式不同。基本型別的值直接存於變數,引用型別變數除佔據一定記憶體空間外,引用的物件實體(也就是new建立的物件)也要佔據一定的空間

2,基本型別存放於棧,引用型別存放於堆。

c#中資料型別中哪些屬於值型別,哪些屬於引用型別

c#中什麼是值型別什麼是引用型別

8樓:小米地瓜來

1***、c#中有兩種型別:

值型別和引用型別:

值型別的變數直接包含他們的資料,而引用型別的變數儲存

引用型別儲存對他們的資料的引用,後者稱為物件:

簡單說:值型別直接儲存其值,引用型別儲存對值得引用.引用型別分為引用和引用的物件。

2***、

值型別:簡單型別、列舉、結構

引用型別: 類型別、介面型別、陣列型別和委託型別

3***、值型別與引用型別的記憶體儲存

單純的說值型別儲存在棧上,引用型別儲存在託管堆上是不對的。

4***、區別:

1、託管堆: 同步塊和方法表, x,y,託管堆上的需要gc來**

執行緒堆疊: 沒有同步塊和方法表

2、值型別賦值是重新建立一個副本

而引用型別的賦值是共享同一塊記憶體(副本),是指向同一塊記憶體(引用型別的名字相當於指向操作)。只是複製引用而不復制被引用識別的物件。(「引用」和「引用的物件」)

3、值型別與引用型別的不同之處就在於值型別的變數直接包括他們的資料,而引用型別的變數把references儲存到他們的資料庫(objects)中。

4、所有的值型別從object中繼承來的。任何型別都不能由值型別派生而來,因此,值型別是封閉式的。

5***什麼時候使用值型別

1)當型別是一個十分簡單的型別,其中沒有成員會修改型別的任何例項欄位

2)型別不需要從其他任何型別繼承

3)型別不會派生出其他任何型別

4)型別的例項較小

5)型別不作為方法引數傳遞,也不作為方法的返回型別使用

6)引用型別可以包含null值,值型別不能(可空型別功能允許將null賦給值型別);

6***什麼時候用ref和out

ref:值型別在傳遞希望成為引用的時候,ref就是告訴傳遞的時候不是拷貝,而是同一個副本。

out:不需要給變數賦初值,使用out也沒必要在外面賦初值,是在內部賦「初值」,out傳遞值是理解成沒有初始化的。

7***深度分析值型別和引用型別(記憶體中的部署)

例子:objectreference r = new object();

關鍵字new在託管堆上分配記憶體空間,並返回一個該記憶體空間的地址。左邊的reference位於棧上,是一個引用,儲存著一個記憶體地址;而這個地址指向的記憶體(位於託管堆上)裡儲存著其內容。

規律:1)引用型別部署在託管堆上

2)值型別總是分配在它宣告的地方:作為欄位時,跟隨其所屬的例項儲存。作為區域性變數時,儲存在棧上。

總結: 引用型別在棧上儲存一個引用,其實際的儲存位置位於託管堆。

8***裝箱與拆箱操作

1) 裝箱操作

裝箱(box)就是將值型別轉換為引用型別的過程。而相反的過程就叫拆箱(unbox)。

裝箱時發生了什麼?

(1)在堆上分配記憶體。因為值型別最終有一個物件代表,所有堆上分配的記憶體量必須是值型別的大小加上容納此物件及其內部結構(比如虛擬方法表)所需的記憶體量。

(2)值型別的值被複制到新近分配的記憶體中

(3)新近分配的物件地址被放到堆疊上,現在它指向一個引用型別。

2)拆箱操作

注:被裝過箱的物件才能被拆箱。

在裝箱的時候,並不需要顯示型別轉換.但在拆箱時需要型別轉換.這是因為在拆箱時物件可以被轉換為任意型別.

注意:裝箱操作可以隱式進行,但拆箱操作必須顯示。

首先,檢查這個物件例項,看它是否為給定值型別的裝箱值。

然後,把這個例項的值拷貝給值型別的變數。

要儘量減少裝箱與拆箱操作

9***問題

1)c#中null和""的區別

string是引用型別:

string str= null 沒有建立記憶體空間,str中存放的是空引用指標.

string str="" str中存放的是指向堆中的指標。有指向

簡單地說:

string str ="";

給你一張白紙;

string str = null;

連白紙也沒有。

string.empty就相當於"" 一般用於字串的初始化

判定為空字串的幾種寫法,按照效能從高到低的順序是:

s.length == 0 優於 s == string.empty 優於 s == ""

2)c#裡面的垃圾**

gc(垃圾**)**的都是可託管**,也就是託管堆中的**

一般定義一個引用變數,它肯定會在堆上面佔用一塊空間,棧上有個地址指向這個儲存位置,只有黨gc發現堆上這個資源在棧上沒有地址指向它的時候才把這塊記憶體**。

非託管資源gc是不會自動**的,例如資料庫連結,檔案等。

c類基金為什麼不能長期持有,基金a類和c類有什麼區別

費用收取機制。c類 是比較適合短期投資的,其費用結構為銷售服務費和贖回費,銷售服務費是會隨著你持有 份額的時間增長而增加的。定投是從長期的進行規劃的,所以通常需要一個較長的期限才可以體現出 定投的作用。需要注意的一點是這裡較長期限是指一年以上。通過計算比較後可以得到費用變化的拐點大概在九個月左右,如...

為什麼類裡要有const函式,const函式在類裡有什麼作用

有兩種const函式,宣告如下 1 const t func 2 t func const 第一種表示返回的是const的型別,也即返回的值不能作為左值,樓主懂的。第二種表示該成員函式不能修改其成員變數的值,即該函式不能改變任何該類的非靜態成員的值。const是一個c語言的關鍵字,它限定一個變數不允...

為什麼顫抖兩種讀音都可以顫抖的讀音兩種都可以,為什麼

顫抖 只有一個讀音,那就是ch n d u。指顫動 哆嗦。形容身體某個部位發抖。顫動,哆嗦,不停地,顫慄地,控制不住地,不停地 可選其一個 抖動。出自楊沫 青春之歌 第一部第四章 在昏暗的燈光下,道靜 的臉色越發蒼白,渾身不住地顫抖。顫抖還有一個出處,那就是巴金的 秋 三 她忽然掉過臉求助似地望著琴...