C陣列為引用還是值型別?若是引用型別,下邊該怎樣理解

時間 2021-09-01 21:17:18

1樓:陽光的雷咩咩

這確實是比較難以理解的現象,網上查了一下,說什麼堆之類的規則,總的來說就是陣列內元素為引用,陣列本身不是(似乎有點牽強。。。)。如果你在函式和呼叫處都加上ref就是完全的物件引用。

參考資料:

2樓:朽木擼其芽

也許可以這樣理解,陣列是值型別,但是他的值是地址,所以你的change(n)函式改變的是陣列地址中的內容,這個是合理的。而change2(n2)則是對地址進行賦值,而陣列是值型別,所以沒有變化。

3樓:

change2(n)的引數n引用n2的值(n指向n2),當n=new的時候,n就指向了new的例項,就和n2脫離關係了,n2還是原來的n2,n是新new的陣列。

如果你學過指標,可以理解為n的指標指向n2,n=new之後,n的指標指向新例項

4樓:

首先明確,陣列是引用型別,以它為引數時按引用傳遞。下來我們來跟蹤一下在執行各步驟中變數的記憶體地址變化情況就一目瞭然了。

main方法中

int n2 = new int ;

這裡會分配一個新的記憶體指標給變數n2,我們假設它指向地址(0x000002725dfdaba0)

當執行change2方法中的n = new int[1] ;後,作業系統會在堆記憶體中開闢新記憶體以便存放new出來的新物件,同時變數n記憶體指標值被從前面的值重置為新開闢的記憶體地值,我們假定它為(0x000002725dfdac10)。讓我們迷惑的玄機就在這裡,n這個指標 它的值發生了變化,而這和n2無關。

再下來就是跳出change2方法體後回到main方法中了,可想而知n2還指向原來的記憶體地址(0x000002725dfdaba0),所以它的值當然還是原來的 int 了。而對於變數n,它會超出變數作用域指標也就不存在了,在合適的時機int[1] 所佔用的堆記憶體就會被gc安全**。

總結,我們也可以更深刻的理解一下,所謂引用型別,它是一個記憶體地址,換個說法它就是一個指標,這個指標指向堆記憶體裡真正存放引用型別的後設資料的地方。只要做new操作 那麼就會開闢新的記憶體地址,當不再有指標指向那些開闢的記憶體地址時,它們就成為gc**的目標。

c#中值型別和引用型別的區別

5樓:大野瘦子

1、速度上的區別

值型別存取速度快,引用型別存取速度慢。

2、用途上的區別

值型別表示實際資料,引用型別表示指向儲存在記憶體堆中的資料的指標或引用。

3、**上的區別

值型別繼承自system.valuetype,引用型別繼承自system.object

4、位置上的區別

值型別的資料儲存在記憶體的棧中,引用型別的資料儲存在記憶體的堆中,而記憶體單元中只存放堆中物件的地址。

5、型別上的區別

值型別的變數直接存放實際的資料,而引用型別的變數存放的則是資料的地址,即物件的引用。

6、儲存位置上的區別

值型別變數直接把變數的值儲存在堆疊中,引用型別的變數把實際資料的地址儲存在堆疊中,而實際資料則儲存在堆中。

例如:字串型別,而堆疊則用於儲存固定長度的資料,如整型型別的資料int(每個int變數佔用四個位元組)。

由資料儲存的位置可以得知,當把一個值變數賦給另一個值變數時,會在堆疊中儲存兩個完全相同的值;而把一個引用變數賦給另一個引用變數,則會在堆疊中儲存對同一個堆位置的兩個引用,即在堆疊中儲存的是同一個堆的地址。

在進行資料操作時,對於值型別,由於每個變數都有自己的值,因此對一個變數的操作不會影響到其它變數;對於引用型別的變數,對一個變數的資料進行操作就是對這個變數在堆中的資料進行操作,

如果兩個引用型別的變數引用同一個物件,實際含義就是它們在堆疊中儲存的堆的地址相同,因此對一個變數的操作就會影響到引用同一個物件的另一個變數。

6樓:匿名使用者

舉例:應用型別:

陣列(派生於system.array)

使用者用定義的以下型別:

類:class(派生於system.object);

介面:inte***ce(介面不是一個「東西」,所以不存在派生於何處的問題。anders在《c# programming language》中說,介面只是表示一種約定[contract]);

委託:delegate(派生於system.delegate)。

object(system.object的別名);

字串:string(system.string的別名)。

可以看出:

引用型別與值型別相同的是,結構體也可以實現介面;

引用型別可以派生出新的型別,而值型別不能;

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

引用型別變數的賦值只複製對物件的引用,而不復制物件本身。而將一個值型別變數賦給另一個值型別變數時,將複製包含的值。

對於最後一條,經常混淆的是string。我曾經在一本書的一個早期版本上看到string變數比string變數效率高;我還經常聽說string是引用型別,string是值型別,等等。

值型別 :

c#的所有值型別均隱式派生自system.valuetype:

結構體:struct(直接派生於system.valuetype);

數值型別:

整型:sbyte(system.sbyte的別名),short(system.

int16),int(system.int32),long (system.int64),byte(system.

byte),ushort(system.uint16),uint (system.uint32),ulong(system.

uint64),char(system.char);

浮點型:float(system.single),double(system.double);

用於財務計算的高精度decimal型:decimal(system.decimal)。

bool型:bool(system.boolean的別名);

使用者定義的結構體(派生於system.valuetype)。

列舉:enum(派生於system.enum);

可空型別(派生於system.nullable泛型結構體,t?實際上是system.nullable的別名)。

每種值型別均有一個隱式的預設建構函式來初始化該型別的預設值。

c# 支援兩種變數型別:

• 值型別 — 這些是內建的基本資料型別,例如 char、int、float等基本資料型別(string除外) 、列舉以及用 struct 宣告的使用者定義型別。

• 引用型別 — 從基本型別構造而來的類和其他複雜資料型別。如:類、介面、陣列和字串。這種型別的變數並不包含型別的例項,而只是包含對例項的引用。

值型別和引用型別的區別在於他們在記憶體中的儲存方式,值型別存貯在棧中,引用型別的記憶體單元中只存放物件的地址,而物件本身存貯在記憶體堆中。

值型別在記憶體中引用的時候會在堆疊中建立一個全新的副本,而不是簡單的引用;而引用型別只是簡單的引用物件的地址。

7樓:風琬鈕若雲

1值型別。

定義時只有型別和變數名。沒有&符號的為值型別。表示本身的值。有自己的記憶體空間。可以不做初始化。

2引用型別。

定義時,型別

&變數名=另一個變數名。

表示引用。自身沒有記憶體空間,使用初始化時的變數空間。是另一個變數名的一個別名。

引用在定義時必須初始化。

8樓:森振華星戊

你得到的結果還是一樣的確良20

和20student3.age

=18;

--->age=18;

student4

=student3;

--->student4=18;

student4.age

=20;

--->student4=20;

--->age=20先前那個age被替了

----->20,20

9樓:匿名使用者

不知道你學過c沒有,演過c的話就很好理解這個問題,引用相當於你在c裡面使用指標,

如:寫一個函式的時候

public int fuction1(ref int a,ret int b)

public static main()

當你在function1中間把a,b變數的值改變後,main函式裡面的a,b 值也就改變了

成了a=2,b=3了

10樓:匿名使用者

它們的區別在於使用的記憶體位置不同:值型別資料儲存在棧上,而引用型別資料儲存在堆上。

值型別直接包含值,換言之,變數引用的位置就是值在記憶體中實際儲存的位置。

引用型別並不直接儲存值,它們儲存的是對一個記憶體位置的引用(記憶體地址),要去那個位置才能找到真正的資料。

------------------《c#本質論》(essential c# 2.0)

c#結構型別是值型別還是引用型別

11樓:微生耕順井錦

c#的值型別包括:結構體(數值型別,bool型,使用者定義的結構體),列舉,可空型別。

c#的引用型別包括:陣列,使用者定義的類、介面、委託,object,字串。

陣列的元素,不管是引用型別還是值型別,都儲存在託管堆上。

引用型別在棧中儲存一個引用,其實際的儲存位置位於託管堆。為了方便,本文簡稱引用型別部署在託管推上。

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

值型別在記憶體管理方面具有更好的效率,並且不支援多型,適合用作儲存資料的載體;引用型別支援多型,適合用於定義應用程式的行為。

C 函式返回型別是引用的問題,C 函式返回值為引用型別時出錯!大神進!

引用就是變數的別名,返回c3的引用,返回的就是c3 c3被清除,再呼叫c3的函式,結果當然不正確 如果返回 i 後,i被清除,但是返回值已經被輸出了,結果是正確的 返回c型別,g函式返回 的是c型別的一個物件,雖然c3被清除,但是返回的物件還能呼叫get函式 你可以在c類中增加一個解構函式,除錯執行...

c語言用指標引用陣列元素,C語言用指標引用陣列元素

琪樂 p 3 是定義一個指向一維陣列的指標,陣列元素為三。也就是說p指向的其實是a 0 a 1 a 2 這樣的形式。p a 其實就是把第0行的首地址賦值給p.所以答案c中p 1 即是把第1行的首地址給p,在此基礎上向後移一位,取出地址中的元素數值。p 1 1 相當於a 1 1 所以是對的。b的形式是...

C 中返回引用和返回值的區別,C 引用返回值 與 返回指標

通常的返回機制將返回值複製到臨時儲存區域中,隨後呼叫程式將訪問該區域.返回引用則程式則呼叫程式將直接訪問返回值.通常引用將指向傳遞給函式的引用,因此呼叫函式實際上是直接訪問自己的一個變數.比如const int fun int a,const int b int x 1,y 2,z z fun x,...