學好C++,爲祖國四化做貢獻。
簡言之:Java都是值傳遞(pass-by-value),而C++中包括值傳遞(pass-by-value)和引用傳遞(pass-by-reference)。
先說Java,先做幾點說明:
在Java中,無非就是兩種類型,即基本類型和從Object繼承下來的對象類型,而對象類型又包括String這種一旦初始化就不可改變內容的類型和BufferString這種可以初始化後可
以改變內容的類型。
然後看一下代碼示例:
- package test;
- public class Test {
- public static void main(String args[]) {
- Integer interger1, interger2;
- int i, j;
- interger1 = new Integer(10);
- interger2 = new Integer(50);
- i = 5;
- j = 9;
- System.out.println("Before Swap, Interger1 is " + interger1);
- System.out.println("Before Swap, Interger2 is " + interger2);
- swap(interger1, interger2);
- System.out.println("After Swap Interger1 is " + interger1);
- System.out.println("After Swap Interger2 is " + interger2);
- System.out.println("Before Swap i is " + i);
- System.out.println("Before Swap j is " + j);
- swap(i, j);
- System.out.println("After Swap i is " + i);
- System.out.println("After Swap j is " + j);
- StringBuffer sb = new StringBuffer("I am StringBuffer");
- System.out.println("Before change, sb is <" + sb + ">");
- change(sb);
- System.out.println("After change sb is <" + sb + ">");
- }
- public static void swap(Integer ia, Integer ib) {
- Integer temp = ia;
- ia = ib;
- ib = temp;
- }
- public static void swap(int li, int lj) {
- int temp = li;
- li = lj;
- lj = temp;
- }
- public static void change(StringBuffer ia) {
- ia.append(", but my content can be changed");
- //ia = new StringBuffer(",but my content can be changed");
- }
- }
輸出:
Before Swap, Interger1 is 10
Before Swap, Interger2 is 50
After Swap Interger1 is 10
After Swap Interger2 is 50
Before Swap i is 5
Before Swap j is 9
After Swap i is 5
After Swap j is 9
Before change, sb is <I am StringBuffer>
After change sb is <I am StringBuffer, but my content can be changed>
這很好解釋,對於基本類型諸如int,傳遞進去的是存放int值的“內存單元”的一個copy,所以函數swap裏面的int和外面的int根本就不是一個東西,當然不能反射出去影響外面
的int。而對於對象類型,我們同樣可以這樣認爲,傳遞進去的是存放對象類型的指針的“內存單元”一個copy(雖然Java裏面沒有指針的概念,但這並不妨礙我們理解)。這樣,
在swap函數裏面,對其指針本身的值做任何操作當然不會影響外面的Integer,因爲interger1和interger2的“內存單元”裏面的值是不變的,其指向的對象類型也是沒有變的。
然後這裏需要說明一個問題,就是StringBuffer這種類型的對象了。因爲其內容是可以改變的,所以change函數裏面的“指針”通過類似“*”的操作,改變了StringBuffer對象的
本身,就顯而易見了。(StringBuffer對象本身只有一個副本)
然後說C++了,裏面的基本類型的諸如int的值傳遞大家都瞭然於胸,就不在這裏廢話了。然後另一種值傳遞可以稱爲指針引用傳遞(pass-by-value argument of pointer)(這個類
似上文說的Java中的對象類型的值傳遞),可以通過*操作,改變指針指向的值。示例程序如下,一看便知:
- #include<iostream.h>
- int main(){
- void test(int*, const char*);
- int i = 1;
- int* iptr = &i;
- cout<<"Before pass-by-value:"<<"\n\n";
- cout<<"i = "<<i<<", It's value of i"<<endl;
- cout<<"&i = "<<&i<<", It's address of i and value of iptr"<<endl;
- cout<<"*iptr = "<<*iptr<<", It's value of i"<<endl;
- cout<<"iptr = "<<iptr<<", It's value of iptr and address of i"<<endl;
- cout<<"&iptr = "<<&iptr<<", It's address of iptr-self"<<"\n\n";
- test(iptr, "pass-by-iptr");
- test(&i, "pass-by-&i");
- return 0;
- }
- void test(int* iiptr, const char* string){
- cout<<"When pass-by-value and :"<<"\n\n";
- cout<<"*iiptr = "<<*iiptr<<", It's value of i"<<endl;
- cout<<"iiptr = "<<iiptr<<", It's value of iiptr and address of i"<<endl;
- cout<<"&iiptr = "<<&iiptr<<", It's address of iiptr-self, different with iptr!"<<"\n\n";
- }
輸出:
Before pass-by-value:
i = 1, It's value of i
&i = 0x0012FF7C, It's address of i and value of iptr
*iptr = 1, It's value of i
iptr = 0x0012FF7C, It's value of iptr and address of i
&iptr = 0x0012FF78, It's address of iptr-self
When pass-by-value and :
*iiptr = 1, It's value of i
iiptr = 0x0012FF7C, It's value of iiptr and address of i
&iiptr = 0x0012FF24, It's address of iiptr-self, different with iptr!
When pass-by-value and :
*iiptr = 1, It's value of i
iiptr = 0x0012FF7C, It's value of iiptr and address of i
&iiptr = 0x0012FF24, It's address of iiptr-self, different with iptr!
在C++裏面的第二種就是引用傳遞了(pass-by-reference)。見如下示例:
- #include<iostream.h>
- int main(){
- void test(int&, const char*);
- int i = 1;
- int &iref = i;
- cout<<"Before pass-by-reference:"<<"\n\n";
- cout<<"i = "<<i<<", It's value of i"<<endl;
- cout<<"&i = "<<&i<<", It's address of i and value of iptr"<<endl;
- cout<<"iref = "<<iref<<", It's value of iref and value of i"<<endl;
- cout<<"&iref = "<<&iref<<", It's address of iref-self, the same as i!"<<"\n\n";
- test(iref, "pass-by-iref");
- test(i, "pass-by-i");
- return 0;
- }
- void test(int &iiref, const char* string){
- cout<<"When pass-by-reference and "<<string<<"\n\n";
- cout<<"iiref = "<<iiref<<", It's value of iiref and value of i"<<endl;
- cout<<"&iiref = "<<&iiref<<", It's address of iiref-self, the same as i!"<<"\n\n";
- }
輸出:
Before pass-by-reference:
i = 1, It's value of i
&i = 0x0012FF7C, It's address of i and value of iptr
iref = 1, It's value of iref and value of i
&iref = 0x0012FF7C, It's address of iref-self, the same as i!
When pass-by-reference and pass-by-iref
iiref = 1, It's value of iiref and value of i
&iiref = 0x0012FF7C, It's address of iiref-self, the same as i!
When pass-by-reference and pass-by-i
iiref = 1, It's value of iiref and value of i
&iiref = 0x0012FF7C, It's address of iiref-self, the same as i!
這裏的引用(reference)說的明白一些,就是被傳遞參數的一個別名,或者更直接的理解就是被傳遞參數自己了,只是名字不同而已。那麼既然自己都被pass過去了,那當然可以在function裏面爲所欲爲了。赫赫。
renki_z對本文亦有貢獻