【写作原由】
今天刚刚刷了一道二叉树路径搜索的题(LeetCode 113 Path
Sum II),在采用熟悉的C++解答之后,用Java语言再次撸了一遍,发现一些问题,特别是参数传递的问题:
【C++】
在C/C++中,参数传递分为两种:值传递和地址传递,其中:
1.值传递:实际参数将值传递给形式参数,对形式参数进行操作不影响实际参数,如:
int main() { int temp=100; printf("before:%d",temp); add1(temp); printf("After1:%d",temp); add2(temp); printf("After2:%d",temp); return 0; } void add1(int x) { x=x+100; } void add2(int *x) { *x=*x+100; }
将实际参数temp传递给函数add1()中的形式参数x,虽然对x进行了操作,但是并不能影响temp的值,这是因为,temp和形式参数x具备不同的内存空间,即程序运行时,系统为他们分别分配了存储空间,既然空间不同,便不可能相互影响,事实上,temp只是为x进行了初始化而已;
2.地址传递:形式参数为实际参数的地址,即将实际参数的存储空间地址传递给形式参数,形如函数add2(),那么,参数temp和x实际上共用了同一存储空间,对其中任何一个操作都会影响另一个。
【Java】
既然是编程语言,便无可避免参数传递,与C++相比,Java存在明显区别,我们知道Java中不存在指针,也就不存在地址传递,Java的参数传递分为:值传递和引用传递
1、值传递,对于基本数据类型 int,char,float,double等,Java语言为值传递,和C/C++基本一致,不再赘述;
2、引用传递,对于对象类型(数组,容器等各种类对象),Java语言为引用传递,何为引用传递呢?以一个具体的实例来分析:
3、严格地讲,Java参数传递为值传递,详见下文分析。
以下内容引用了文章:http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html
public class ParameterTransfer { public static void main(String[] args) { String[] array = new String[] {"huixin"}; System.out.println("调用reset方法前array中的第0个元素的值是:" + array[0]); reset(array); System.out.println("调用reset方法后array中的第0个元素的值是:" + array[0]); } public static void reset(String[] param) { param[0] = "hello, world!"; } }
运行结果:
调用reset方法前array中的第0个元素的值是:huixin 调用reset方法后array中的第0个元素的值是:hello, world!
string是Java的一个类,array是string类的类变量,我们用new方法对其进行了实例化,array称为string对象“huixin”的一个引用;从内存模型的角度来看,内存空间分为两种:栈空间(stack)和堆空间(heap),类变量array和param都存放在栈空间中,而对象“huixin”则存放在对空间中,array称为string对象“huixin”的一个引用,实际上,array存放的是“huixin”的地址,如图所示。当执行reset方法时,我们将类变量array的值传递给了类变量param,那么param中存放的实际上也是“huixin”的地址,即array与param存放的是同一存储空间的地址,严格地讲,这是“值传递”,当我们对param进行操作时,改变的当然也是array所引用对象的值,如图2.