关于按值传递和按引用传递(送给这个方面的新手——包括我自己)
我記得剛上大學(xué)我們學(xué)院就給我們開了第一門專業(yè)課——高級(jí)語言程序設(shè)計(jì)。在函數(shù)一節(jié)里面,首先要學(xué)到形式參數(shù)和實(shí)際參數(shù),然后就學(xué)了按值傳遞和按引用傳遞,當(dāng)時(shí)學(xué)得那叫一個(gè)云里霧里啊,再加上后面還學(xué)了個(gè)指針,弄得我完全是丈二和尚摸不著頭腦……好在我記住了一段話,并把它做為金科玉律,還是讓我勉強(qiáng)在編程的時(shí)候不會(huì)搞出太多錯(cuò)來。
?
這段話就是:凡是在函數(shù)定義里面的形式參數(shù)為類類型的,函數(shù)調(diào)用時(shí)實(shí)際參數(shù)為對(duì)象,此時(shí)為按引用傳遞;凡是在函數(shù)定義里面的形式參數(shù)為值類型的,函數(shù)調(diào)用時(shí)實(shí)際參數(shù)為值,此時(shí)為按值傳遞。
?
還好,這句話有些繞口但不是特別繞口。
現(xiàn)如今,我編程再也不用C和C++了(我皈依到Microsoft門下),真正做應(yīng)用的時(shí)候,那些問題我也從來不再考慮,可是前幾天同學(xué)弄的一個(gè)問題著實(shí)讓我迷糊了半天。
總之,我先把代碼寫下來吧。在VS中新建一個(gè)控制臺(tái)應(yīng)用程序,改寫其Program.cs文件如下:
?
Codeusing?System;
using?System.Collections.Generic;
using?System.Text;
namespace?Test
{
????class?Program
????{
????????static?void?Main(string[]?args)
????????{
????????????int?i?=?0;
????????????string?s?=?"hello";
????????????A?a?=?new?A();
????????????a.i?=?10;
????????????a.s?=?"abcd";?
????????????Console.WriteLine(i);
????????????Console.WriteLine(s);
????????????Console.WriteLine(a);
????????????Console.WriteLine("----------------------------------------------------------");
????????????changeInt(i);
????????????changeString(s);
????????????changeA(a);
????????????Console.WriteLine(i);
????????????Console.WriteLine(s);
????????????Console.WriteLine(a);
????????????Console.Read();
????????}
????????private?static?void?changeInt(int?i)
????????{
????????????i++;
????????}
????????private?static?void?changeString(string?s)
????????{
????????????s?=?"world";
????????}
????????private?static?void?changeA(A?a)
????????{
????????????a.i++;
????????????a.s?=?"hijk";
????????}
????????private?class?A
????????{
????????????public?int?i;
????????????public?string?s;
????????????public?override?string?ToString()
????????????{
????????????????return?"The?int?value?is?"?+?i.ToString()?+?"?and?the?string?value?is?"?+?s;
????????????}
????????}
????}
}
有興趣的話,先想想在控制臺(tái)里會(huì)打出來什么結(jié)果——當(dāng)然啦,這種小兒科只能糊弄像我這樣的菜鳥。。。。結(jié)果我先寫下來
?
Code0
hello
The?int?value?is?10?and?the?string?value?is?abcd
----------------------------------------------------------
0
hello
The?int?value?is?11?and?the?string?value?is?hijk
?
其實(shí)我也先為自己辯解幾句,上面這東西迷糊人,Microsoft也有責(zé)任,從前在C的年代,哪有string這東西,什么時(shí)候我們都用char*,這肯定是個(gè)指針。現(xiàn)如今說int是值類型吧,它有個(gè)Int32的結(jié)構(gòu)(Java更狠,直接就是Integer的類),說String是個(gè)引用吧,它還有個(gè)小寫的string的關(guān)鍵字。微軟讓高人方便了,卻讓像我這樣的矬人傻了眼。
?
不多說,看上面代碼。明眼人一看,第一個(gè)changeInt(int i)的方法就是狗屁,這顯然是按值傳遞,以前那個(gè)i紋絲不動(dòng);再看第三個(gè)changA(A a),這個(gè)方法也沒什么,A是我定義的類型,肯定是按引用傳遞,方法里面改了A的公共字段,外面的A也得跟著改;最后看一下changeString(string s),直說了吧,這個(gè)也是按引用傳遞,在函數(shù)里面改了s,白癡問題來了,函數(shù)里面改了s,怎么改完了輸出不跟著變呢?
?
其實(shí)這段程序純是騙小孩玩的,不管我傳的是個(gè)string還是個(gè)String,都是一碼事,全是按引用傳遞的。這段代碼和那個(gè)changeA(A a)的區(qū)別就在于,changeA改的是a的公共字段,而changeString改的是s本身。如果我在changeA的第一句添上a=new A();再運(yùn)行這段代碼,就會(huì)發(fā)現(xiàn)最后一句輸出的a和從前的結(jié)果是一樣的。
?
說到底,C#和Java說是不用指針,那不可能,沒指針哪來的NullReferenceException和NullPointerException啊。對(duì)于按引用傳遞的對(duì)象來說,函數(shù)在調(diào)用的時(shí)候,創(chuàng)建了一個(gè)新的指針(Java中的pointer、C#中的reference),指向的是那個(gè)對(duì)象。這個(gè)東西存的就是那個(gè)對(duì)象在內(nèi)存里的地址,和C里面的指針是一個(gè)東東,只是不讓+、-而已。然后我們?cè)赾hangeString里把這個(gè)地址指向了"world"的內(nèi)存地址,這里改變的只是新創(chuàng)建出來的那個(gè)指針,而原來那個(gè)指向"hello"的沒跟著變,所以打印語句打出來的還是hello。對(duì)于changeA來說,新創(chuàng)建出來的指針指向地址的和Main函數(shù)的a指向的是一個(gè)地方,由于在changeA里面我們沒給它重新定向,所以我改了changeA里面的a,Main函數(shù)里面的a也跟著改了。
?
現(xiàn)在那條金科玉律還是對(duì)的了,只不過我要恬不知恥地加上:看吧,如果你用VS來開發(fā)程序,對(duì)于函數(shù)按引用傳遞的參數(shù)來說,如果你改的東西是.出來的,那就改變了函數(shù)外面那個(gè)對(duì)象,如果你把形參拿下來直接后面就放=了,那外面就不改啦,嘿嘿嘿^_^
?
PS:看客請(qǐng)不要逼問我指針的定義是啥,如果你認(rèn)為C#里面reference不是指針我也不反對(duì)
轉(zhuǎn)載于:https://www.cnblogs.com/wodehuajianrui/archive/2008/07/30/1256710.html
總結(jié)
以上是生活随笔為你收集整理的关于按值传递和按引用传递(送给这个方面的新手——包括我自己)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OWC的问题——散点图与折线图如何才能同
- 下一篇: 没了良心