黑马程序员技术交流社区

标题: 数组元素交换 [打印本页]

作者: Himoriarty    时间: 2015-4-14 17:49
标题: 数组元素交换
public class Test
{
          public static void main(String[] args)
          {
                       int[] a = {1,2};
                       swap(a[0],a[1]);
                      System.out.println(a[0] + " " + a[1]);
           }
          public static void swap(int n1, int n2)
           {
                      int temp = n1;
                       n1 = n2;
                       n2 = temp;
           }
}
为什么结果是没交换?

作者: 君嘘    时间: 2015-4-14 17:49
这里有个概念:
基本数据类型,形式参数的改变不影响实际参数的改变。
引用数据了性,形式参数的改变影响实际参数的改变。

楼主的swap方法中,改变的是基本数据类型int。所以无论你怎么替换,实际参数也不会改变的。

因为你swap方法运行的时候,虚拟机会在栈内存中开辟一个空间,空间里面定义了两个变量n1和n2.
然后将arr[0]和arr[1]的值传给了n1和n2。

arr[0],arr[1]其实和n1,n2没什么关系。你无论怎么操作,操作的都只是n1和n2。
这就是基本数据类型的特点。

然后如果像2楼那样:
public static void swap(int[] arr, int n1, int n2)
int temp = arr[n1];
arr[n1] = arr[n2];
arr[n2] = temp;
楼主也知道数组打印出来的是地址值吧。当数组作为参数传给swap,其实传过去的是一个引用地址。然后形式参数当然也就能百变实际参数。

这个概念涉及到java的内存机制,我这里发图片打字都很不方便。所以建议你认真看看毕老师的视频,毕老师讲的所有跟内存有关的知识点都是重中之重。
作者: 静心明德    时间: 2015-4-14 18:41
我给你了详细的解答,相信你能明白。

  1. //知识点:函数调用参数值传递问题(重点+难点)
  2. public class Test1 {

  3.         public static void main(String[] args) {
  4.                 int[] a = { 1, 2 };
  5.                 swap(a,0,1);        //修改1:要改变的是数组这个对象的结构,必须要传引用变量的值
  6.                 System.out.println(a[0] + " " + a[1]);
  7.         }

  8.         public static void swap(int[] arr, int n1, int n2) {//修改2:参数修改
  9.                 //这样才是正真交换了数组里面的两个值的顺序。你之前的那个只是改变了在这个方法里面的两个值的顺序,除了这个方法就没有作用了。
  10.                 int temp = arr[n1];
  11.                 arr[n1] = arr[n2];
  12.                 arr[n2] = temp;
  13.         }
  14. }
复制代码

作者: Himoriarty    时间: 2015-4-14 20:15
静心明德 发表于 2015-4-14 18:41
我给你了详细的解答,相信你能明白。

这个理论依据是什么,是因为局部变量的原因,还是传址,改变的是地址的值,元素值没变。还是什么
作者: 棉棉502    时间: 2015-4-14 20:24
swap方法中的形式参数是基本数据类型(四类八种)时,传递的是实际值,与变量的值无关;只有将swap中的形式参数设为引用型的参数,传递地址值,才会改变变量的值.
作者: 静心明德    时间: 2015-4-14 20:51
Himoriarty 发表于 2015-4-14 20:15
这个理论依据是什么,是因为局部变量的原因,还是传址,改变的是地址的值,元素值没变。还是什么 ...

是传值,改变的是地址的值,属于引用数据类型的传值问题,对啊,改变的就是地址值。
作者: itheima_llt    时间: 2015-4-14 21:42
解决了没有,没有解决我就告诉你,一张图包懂!
作者: 机智的黄图哥    时间: 2015-4-15 00:33
这么说 你现在往方法里面传递的是具体的数值 而不是数组在内存中的引用变量 无论你下面怎么操作 只要不是 通过引用地址改变的值都是不会改变的 所以上面的值你在打印的时候还是原先的值  除非你从新指向新的地址值
但是内存中原先的值也不会改变 只是会等垃圾回收机制来回收他
作者: 261406938    时间: 2015-4-15 01:06
交换内容没有返回啊,只是函数内部交换了 回主函数没交换
作者: Himoriarty    时间: 2015-4-15 09:12
君嘘 发表于 2015-4-14 22:01
这里有个概念:
基本数据类型,形式参数的改变不影响实际参数的改变。
引用数据了性,形式参数的改变影响实 ...

非常感谢,明白了
作者: 智远    时间: 2015-4-15 16:59
变量作用域的问题,n1和n2是形式参数且交换了,但实际参数(数组)没变。
作者: windform    时间: 2015-4-15 19:27

public class Test
{
          public static void main(String[] args)
          {
                       int[] a = {1,2};
                       swap(a[0],a[1]);
                      System.out.println(a[0] + " " + a[1]);
           }
          public static void swap(int n1, int n2)
           {
                      int temp = n1;
                       n1 = n2;
                       n2 = temp;
           }
}

void swap(int n1 ,int n2)函数中形参n1,n2其实是主函数中数组 元素a[0] a[1]的的备份,
你交换的是n1,n2内存里面的值,并没有动a[0],a[1]的修改内存,所自然就没有交换了的。
将函数改为这样
void swap(int [ ] arr)
{
     int tmp = arr[0];
    arr[0] = arr[1];
  arr[1] = tmp;
}
在主函数中将数组的引用a传递给arr,那么arr也可以引用主函数中数组的内存,
那么在swap中的arr[0]和主函数 的a[0]其实是同一个存储单元
arr[1]和主函数中的a[1]是同一个存储单元,那么就可以就可以在调用函数中实现主函数中的数组的值交换了。





作者: windform    时间: 2015-4-15 19:39
class Swap
{
        public static void main(String[ ] args)
        {
                int[] a = {1,2};
                System.out.println(a[0]+" " + a[1]);
                swap(a);
                System.out.println(a[0]+" " + a[1]);
        }

        public static void swap(int[] arr)
        {
                int tmp = arr[0];
                arr[0] = arr[1];
                arr[1] = tmp;
        }
}

测试输出结果
1 2
2 1
作者: 哔哩哔哩    时间: 2015-4-15 21:35
君嘘 发表于 2015-4-14 22:01
这里有个概念:
基本数据类型,形式参数的改变不影响实际参数的改变。
引用数据了性,形式参数的改变影响实 ...

+10086     
作者: 进击的华仔    时间: 2015-4-15 21:41
学习了

作者: 优质码农    时间: 2015-4-15 21:48
接受参数应该是数组
作者: 18561271203    时间: 2015-4-15 22:22
你的swap方法中,只是只换了两个数的值,但是没有返回给要操作的数组,系统并不知道你要换哪个数组中的元素。
1.要么向二楼那样传入需要操作的数组。
2.要么你就直接把换值操作直接写出,不再定义函数去完成换值动作。
作者: 优质码农    时间: 2015-4-16 07:00
你这交换没有实质的把数组内存的地址交换,只是把两个数值交换了吗,没有意义
作者: wx348602984    时间: 2015-4-16 19:37
数组是引用数据类型,所以你传参的时候也应该用引用数据类型来接收,
你所写的只是把int类型的a,b交换了
可以这样写:
public class Aa {

        public static void main(String[] args) {
                int [] a= {1,2};
                method(a);
                System.out.println(a[0]+" "+a[1]);
        }

        public static void method(int[] b) {
               
                int temp = b[0];
                b[0]= b[1];
                b[1]=temp;
        }


}
作者: wx348602984    时间: 2015-4-16 19:40
数组是引用数据类型,所以你传参的时候也应该用引用数据类型来接收,
你所写的只是把int类型的a,b交换了
可以这样写:
public class Aa {
public static void main(String[] args) {
  int [] a= {1,2};
  method(a);
  System.out.println(a[0]+" "+a[1]);
}
public static void method(int[] b) {
  
  int temp = b[0];
  b[0]= b[1];
  b[1]=temp;
}

}


作者: synhm    时间: 2015-4-16 19:59
我是来学习的。。。。
作者: 忘言    时间: 2015-4-16 20:44
你交换的是形式参数的值,并没有改变实际参数

public class swape
{
          public static void main(String[] args)
          {
                       int[] a = {1,2};
                       swap(0,1,a);
                      System.out.println(a[0] + " " + a[1]);
           }
          public static void swap(int n1, int n2, int a[])
           {
                      int temp = a[n1];
                       a[n1] = a[n2];
                       a[n2] = temp;
           }
}
作者: break    时间: 2015-4-16 22:06
不能水啊   也在学习
作者: Taekwon-boy    时间: 2015-4-16 23:53
区分形参,实参
作者: YQliang    时间: 2015-4-17 11:09
没有返回值,就等于是你干了活,啥都没有给老板汇报一样,要对返回值进行接收;而且你传进去的是元素,不是引用,要是你不返回值,可以把数组的引用传进去就OK了;
作者: 候长亮    时间: 2015-5-10 09:28
可是这样也只是交换两个,有点简单了,如果全部交换,用循环遍历,不管多少个都给交换。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2