• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
夜真寒
博客园    首页    新随笔    联系   管理    订阅  订阅

Java与C++函数参数传递比较

简言之:Java都是值传递(pass-by-value),而C++中包括值传递(pass-by-value)和引用传递(pass-by-reference)。

先说Java,先做几点说明:

在Java中,无非就是两种类型,即基本类型和从Object继承下来的对象类型,而对象类型又包括String这种一旦初始化就不可改变内容的类型和BufferString这种可以初始化后可

以改变内容的类型。

然后看一下代码示例:

 

java 代码
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中的对象类型的值传递),可以通过*操作,改变指针指向的值。示例程序如下,一看便知:

cpp 代码
#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)。见如下示例:

cpp 代码
  1. #include<iostream.h>   
  2. int main(){   
  3.  void test(int&, const char*);   
  4.  int i = 1;   
  5.  int &iref = i;   
  6.  cout<<"Before pass-by-reference:"<<"\n\n";   
  7.  cout<<"i = "<<i<<", It's value of i"<<endl;   
  8.  cout<<"&i = "<<&i<<", It's address of i and value of iptr"<<endl;   
  9.  cout<<"iref = "<<iref<<", It's value of iref and value of i"<<endl;   
  10.  cout<<"&iref = "<<&iref<<", It's address of iref-self, the same as i!"<<"\n\n";   
  11.     
  12.  test(iref, "pass-by-iref");   
  13.   
  14.  test(i, "pass-by-i");   
  15.   
  16.  return 0;   
  17. }   
  18.   
  19. void test(int &iiref, const char* string){   
  20.  cout<<"When pass-by-reference and "<<string<<"\n\n";   
  21.  cout<<"iiref = "<<iiref<<", It's value of iiref and value of i"<<endl;   
  22.  cout<<"&iiref = "<<&iiref<<", It's address of iiref-self, the same as i!"<<"\n\n";   
  23. }   
  24.   

输出:

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里面为所欲为了。

posted @ 2011-10-28 18:50  夜真寒  阅读(1774)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3