java中函数参数传值还是传地址

版权声明:本文为博主原创文章,转载希望能注明出处,感谢。 https://blog.csdn.net/u010126792/article/details/63771475

今天和大家探讨个简单的小问题大笑

Java中函数参数是传值还是传地址

    刚接触C语言时有一道题困惑了我好久,就是交换两个数的值,本来以为相当简单,只要把要交换的a,b传进去,在函数里面利用一个中间变量就可以完成参数的交换,但如何修改程序都不行,大家不要笑,曾记否刚开始学习是对于a=b和形参实参我就迷惑了好久,好久-^^-。很明显下面的程序无法完成交换。

#include<stdio.h>

void swap(int,int);

void main(){

  inta=5;

  intb=7;

 printf("a=%d b=%d\n",a,b);//a=5 b=7

 swap(a,b);

 printf("a=%d b=%d\n",a,b);//a=5 b=7

}

void swap(int a,int b){

 inttemp;

 temp=a;

 a=b;

 b=temp;

}


改成传地址很简单利用指针就可以完成两个数的交换

#include<stdio.h>

void swap(int *,int *);

void main(){

  inta=5;

  intb=7;

 printf("a=%d b=%d\n",a,b);//a=5 b=7

 swap(&a,&b);//此处传出a,b的地址,利用取地址符

 

 printf("a=%d b=%d\n",a,b);//a=7 b=5

}

 

void swap(int *a,int *b){//传入地址,就可以完成两个说

 inttemp;

 temp=*a;

 *a=*b;

 *b=temp;

}


     C#近几年作为脚本语言很火,由于微软的强大实力和VisualStudio号称功能最强大的编译器C#发展的很不错,java中很多特性其实是晚于C#出现的,不能说谁抄袭谁,毕竟java比C#出现的早,如果当初sun不对微软施加压力,微软保持对java的热情,不知道现在会如何。随着微软进一步拥抱linux,听说最近出的2017 VisualStudio已经可以开发android应用了。

C#语言有专门的关键字可以表示是传值还是传地址ref。

 

  static void swap(int a, int b)  //这个函数将以传值的方式运行 

  {

 inttemp;

 temp=a;

 a=b;

 b=temp;

  }

  

 2      

 static void swap(ref int i, ref int t) // 这个函数将会以传址的方式进行运算.          {int temp;

 temp=a;

 a=b;

 b=temp;

}


函数内部完全相同,结果却是不同的,所以c语言和C#是存在传值传地址的概念的。

 

       Java中程序员无法直接操作指针,对于传值还是传地址很模糊,但我们知道java中变量分为两类,一类是基本变量,一类是引用。其实当我们把实参a,b传进函数后,就相当于把a,b的值分别传给了函数用于接收a,b的局部变量,那么不管是传进去引用还是值,实参a,b的值都不会被改变,因为操作的时函数中接收a,b传递的值的局部变量,函数执行完毕,这两个局部变量也就不存在了。那为什么传进去引用可以修改a,b的值呢,这是不违反我上面说的原理的,传引用相当于把a,b的内存地址传递进函数,函数的局部变量接收了a,b的地址,a,b的引用地址是无法在函数内部被改变的,但是a,b指向的值是可以改变的。

     Java中无论传值还是传引用都是传的参数的副本,副本只在函数内部有效。而当传引用时,传进去的是自己副本的地址,地址无法被改变但是地址指向的值可以被改变。所以可以说java中都是在传值。

实例:

publicstaticvoidmain(String[]args){

      intnum=4;

      test1(num);

      System.out.println(num);//4

      Stringstr="lidx";

      test2(str);

      System.out.println(str);//lidx

      StringBuffersb=new StringBuffer("lidx");

      test3(sb);

      System.out.println(sb);//lidxadd

      String[]arr={"lidx","lidx"};

      test4(arr);

      System.out.println(Arrays.asList(arr).toString()+"");//[add,lidx]

      Testtest=new Test(4);

      test5(test);

      System.out.println(test.getAge());//5

 

   }

所以说java中都可以看做是传值,普通类型参数传递的是参数的值的副本,在函数内部值修改副本,无法对原始数据产生影响,当引用作为参数时,传递的是引用类型的地址,函数内部接收引用的地址的副本,对引用地址所指向的值可以进行修改,但引用的地址是无法修改的,相当于引用地址的值无法修改。StringStringBuffer作为参数为什么不同,相信了解String特性的都知道,String生成实例之后他的值无法修改,如果对它进行修改会产生新的对象,所以String的地址传入函数内部,函数内部对它指向的值进行操作,最终却生成了另外一个对象,而上面所说无法对原String的地址修改,所以对于新生成的String对象无法影响原来的String对象,并且它的生命周期只在函数内部。

猜你喜欢

转载自blog.csdn.net/u010126792/article/details/63771475