java及C++中傳值傳遞、引用傳遞和指針?lè)绞降睦斫?/h1>
更新時(shí)間:2014年09月22日 11:23:07 投稿:hebedich
為什么 Java 只有值傳遞,但 C++ 既有值傳遞,又有引用傳遞呢?今天我們就來(lái)探討下這個(gè)問(wèn)題,有需要的朋友可以參考下
java的值傳遞理解:
代碼1:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
StringBuffer buffer= new StringBuffer("colin");
SChange(buffer);
System.out.println( buffer);
}
public static void SChange (StringBuffer str) {
str= new StringBuffer("huang");
}
}
代碼2:
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
StringBuffer buffer= new StringBuffer("colin");
SChange(buffer);
System.out.println( buffer);
}
public static void SChange (StringBuffer str) {
//str= new StringBuffer("huang"); str.append(" huang");
}
}
再分別用兩張圖來(lái)解釋上面的代碼1、代碼2:
原始狀態(tài)

代碼1圖解:

代碼2理解:

代碼一中, copy的那個(gè)引用, 指向了一個(gè)新的對(duì)象。 但原對(duì)象還是沒(méi)有變化的。
代碼二中, copy的那個(gè)引用, 把原對(duì)象改變了。
這就是Java的值傳遞。
C++中兩種傳遞的區(qū)別:
對(duì)于C++值傳遞、引用傳遞、指針?lè)绞接萌缦麓a理解,自己運(yùn)行測(cè)試
#include <stdio.h>
#include <iostream>
#include <typeinfo>
void ByValue(int a)
{
a = a + 1;
}
void ByRef(int& a)
{
a = a + 1;
}
void ByPointer(int* a)
{
*a = *a + 1;
}
int main(int argv, char** args)
{
int v = 1;
ByValue(v);
ByRef(v);
// Pass by Reference ByPointer(&v);
// Pass by Value int* vp = &v;
ByPointer(vp);
std::cout << v << std::endl; // std::cout << typeid(vp).name() << std::endl;
// std::cout << typeid(&vp).name() << std::endl; std::cout << "end" << std::endl;
}
第一個(gè)是值傳遞,第二個(gè)函數(shù)是引用傳遞,但是后面兩種,同一個(gè)函數(shù),一次調(diào)用是Call by reference, 一次是Call by value。
因?yàn)椋?/p>
ByPointer(vp); 沒(méi)有改變vp,其實(shí)是無(wú)法改變。值傳遞
ByPointer(&v); 改變了v。引用傳遞(你可能會(huì)說(shuō),這傳遞的其實(shí)是v的地址,而B(niǎo)yPointer無(wú)法改變v的地址,所以這是Call by value。這聽(tīng)上去可以自圓其說(shuō),但是v的地址,是個(gè)純數(shù)據(jù),在調(diào)用的方代碼中并不存在,對(duì)于調(diào)用者而言,只有v,而v的確被ByPointer函數(shù)改了,這個(gè)結(jié)果,正是Call by reference的行為。從行為考慮,才是求值策略的本意。如果把所有東西都抽象成值,從數(shù)據(jù)考慮問(wèn)題,那根本就沒(méi)有必要引入求值策略的概念去混淆視聽(tīng)。)
nob:以上理解認(rèn)可,補(bǔ)充指針?lè)绞娇梢允褂脙煞N方式,值傳遞:傳遞一個(gè)指針;引用傳遞:傳遞一個(gè)變量的地址或者引用;如果使用typeid(x).name()查看&v和vp發(fā)現(xiàn)都是Point類型,所以兩種表現(xiàn),同一種結(jié)果。你可能會(huì)想我這樣
ByValue(&v); //error
,而在C++中傳遞不同類型的參數(shù)直接編譯不通過(guò)。
總結(jié):
所以我覺(jué)得傳值還傳引用先看內(nèi)存上怎么走就行了
share內(nèi)存就是傳引用,copy內(nèi)存就是傳值(先拋開(kāi)一些特殊情況)
這樣的話:
C/C++:默認(rèn)傳值,引用傳引用,指針單獨(dú)理解(指針可以理解為既可以傳值、也可以傳引用,而產(chǎn)生結(jié)果相同)
JAVA:基礎(chǔ)數(shù)據(jù)類型值傳遞,對(duì)象也是值傳遞(把這個(gè)對(duì)象的引用copy了一份)
C#:值類型傳值,引用類型傳引用,ref/out特殊理解
JAVA和C#的string要特殊理解,表象是傳值,實(shí)際要看虛擬機(jī)實(shí)現(xiàn)
相關(guān)文章
-
聊聊java中一些減少if else 的編碼習(xí)慣的方法
這篇文章主要介紹了聊聊java中一些減少if else 的編碼習(xí)慣的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧 2019-08-08
-
java實(shí)現(xiàn)MD5加密算法的實(shí)例代碼
這篇文章主要介紹了java實(shí)現(xiàn)MD5加密算法的實(shí)例代碼,有需要的朋友可以參考一下 2013-12-12
-
Java經(jīng)驗(yàn)點(diǎn)滴:處理沒(méi)有被捕獲的異常
Java經(jīng)驗(yàn)點(diǎn)滴:處理沒(méi)有被捕獲的異常... 2006-12-12
-
SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式
這篇文章主要介紹了SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2023-08-08
-
Java實(shí)現(xiàn)仿淘寶滑動(dòng)驗(yàn)證碼研究代碼詳解
這篇文章主要介紹了Java實(shí)現(xiàn)仿淘寶滑動(dòng)驗(yàn)證碼研究代碼詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下 2016-06-06
最新評(píng)論
java的值傳遞理解:
代碼1:
public class Test { /** * @param args */ public static void main(String[] args) { StringBuffer buffer= new StringBuffer("colin"); SChange(buffer); System.out.println( buffer); } public static void SChange (StringBuffer str) { str= new StringBuffer("huang"); } }
代碼2:
public class Test { /** * @param args */ public static void main(String[] args) { StringBuffer buffer= new StringBuffer("colin"); SChange(buffer); System.out.println( buffer); } public static void SChange (StringBuffer str) { //str= new StringBuffer("huang"); str.append(" huang"); } }
再分別用兩張圖來(lái)解釋上面的代碼1、代碼2:
原始狀態(tài)
代碼1圖解:
代碼2理解:
代碼一中, copy的那個(gè)引用, 指向了一個(gè)新的對(duì)象。 但原對(duì)象還是沒(méi)有變化的。
代碼二中, copy的那個(gè)引用, 把原對(duì)象改變了。
這就是Java的值傳遞。
C++中兩種傳遞的區(qū)別:
對(duì)于C++值傳遞、引用傳遞、指針?lè)绞接萌缦麓a理解,自己運(yùn)行測(cè)試
#include <stdio.h> #include <iostream> #include <typeinfo> void ByValue(int a) { a = a + 1; } void ByRef(int& a) { a = a + 1; } void ByPointer(int* a) { *a = *a + 1; } int main(int argv, char** args) { int v = 1; ByValue(v); ByRef(v); // Pass by Reference ByPointer(&v); // Pass by Value int* vp = &v; ByPointer(vp); std::cout << v << std::endl; // std::cout << typeid(vp).name() << std::endl; // std::cout << typeid(&vp).name() << std::endl; std::cout << "end" << std::endl; }
第一個(gè)是值傳遞,第二個(gè)函數(shù)是引用傳遞,但是后面兩種,同一個(gè)函數(shù),一次調(diào)用是Call by reference, 一次是Call by value。
因?yàn)椋?/p>
ByPointer(vp); 沒(méi)有改變vp,其實(shí)是無(wú)法改變。值傳遞
ByPointer(&v); 改變了v。引用傳遞(你可能會(huì)說(shuō),這傳遞的其實(shí)是v的地址,而B(niǎo)yPointer無(wú)法改變v的地址,所以這是Call by value。這聽(tīng)上去可以自圓其說(shuō),但是v的地址,是個(gè)純數(shù)據(jù),在調(diào)用的方代碼中并不存在,對(duì)于調(diào)用者而言,只有v,而v的確被ByPointer函數(shù)改了,這個(gè)結(jié)果,正是Call by reference的行為。從行為考慮,才是求值策略的本意。如果把所有東西都抽象成值,從數(shù)據(jù)考慮問(wèn)題,那根本就沒(méi)有必要引入求值策略的概念去混淆視聽(tīng)。)
nob:以上理解認(rèn)可,補(bǔ)充指針?lè)绞娇梢允褂脙煞N方式,值傳遞:傳遞一個(gè)指針;引用傳遞:傳遞一個(gè)變量的地址或者引用;如果使用typeid(x).name()查看&v和vp發(fā)現(xiàn)都是Point類型,所以兩種表現(xiàn),同一種結(jié)果。你可能會(huì)想我這樣
ByValue(&v); //error
,而在C++中傳遞不同類型的參數(shù)直接編譯不通過(guò)。
總結(jié):
所以我覺(jué)得傳值還傳引用先看內(nèi)存上怎么走就行了
share內(nèi)存就是傳引用,copy內(nèi)存就是傳值(先拋開(kāi)一些特殊情況)
這樣的話:
C/C++:默認(rèn)傳值,引用傳引用,指針單獨(dú)理解(指針可以理解為既可以傳值、也可以傳引用,而產(chǎn)生結(jié)果相同)
JAVA:基礎(chǔ)數(shù)據(jù)類型值傳遞,對(duì)象也是值傳遞(把這個(gè)對(duì)象的引用copy了一份)
C#:值類型傳值,引用類型傳引用,ref/out特殊理解
JAVA和C#的string要特殊理解,表象是傳值,實(shí)際要看虛擬機(jī)實(shí)現(xiàn)
相關(guān)文章
聊聊java中一些減少if else 的編碼習(xí)慣的方法
這篇文章主要介紹了聊聊java中一些減少if else 的編碼習(xí)慣的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08java實(shí)現(xiàn)MD5加密算法的實(shí)例代碼
這篇文章主要介紹了java實(shí)現(xiàn)MD5加密算法的實(shí)例代碼,有需要的朋友可以參考一下2013-12-12Java經(jīng)驗(yàn)點(diǎn)滴:處理沒(méi)有被捕獲的異常
Java經(jīng)驗(yàn)點(diǎn)滴:處理沒(méi)有被捕獲的異常...2006-12-12SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式
這篇文章主要介紹了SpringBoot之整合MyBatis實(shí)現(xiàn)CRUD方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Java實(shí)現(xiàn)仿淘寶滑動(dòng)驗(yàn)證碼研究代碼詳解
這篇文章主要介紹了Java實(shí)現(xiàn)仿淘寶滑動(dòng)驗(yàn)證碼研究代碼詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06