有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

将数组作为参数传递:C和Java

在我提问之前,我会注意到我知道:

  1. 在C语言中,我们可以通过值调用方法,也可以通过引用调用方法
  2. 在Java中,我们只能按值调用方法(当我们传递对象时,我们传递的是对象引用的值,而不是对象引用本身)
  3. 在C和Java上下文中,指针和引用之间存在差异

现在谈问题:

考虑数组:

arr = {1,2,3,4,5} //len =5

在C中,我可以做以下两件事:

foo(arr, len);
bar (arr+ 2, len -2);

函数定义:

foo(int *a, int l) {
  ...
  printf("%d", &a[0];  //prints 1
  ...
}

bar (int *a, int l){
  printf("%d", &a[0];  //prints 3
  ...
}

我们可以看到,函数栏中的数组a以值3开头,因为它包含arr[2](原始数组)的地址。如果要将子数组视为起始索引为0的新数组,这是在C中传递数组的一种简洁方法

我想知道,尽管以下调用在C和Java中具有不同的含义,但Java中是否也可以实现同样的功能:

foo(arr);

共 (5) 个答案

  1. # 1 楼答案

    Java缺少本机的切片函数(比如C中关于数组开头的隐式切片函数,或者几种现代语言中的显式切片函数),但是如果需要,可以很容易地构建自己的类来包装数组、索引和长度

  2. # 2 楼答案

    在C和Java中传递数组时的想法也是一样的

    在Java中,所有传递给对象的都是对它们的引用,即指针。在Java中,你永远不会说:A*A=newa();你只需要写一个A=新的A();缺少*就是区别。否则,A的行为与指针完全相同

    原语变量按值传递

  3. # 3 楼答案

    如果您的问题是关于是否可以通过执行arr + 2中的指针算法来寻址数组的元素,那么答案是否定的

    但是,通过传入数组和要开始读取数组的位置,可以实现相同的效果

  4. # 4 楼答案

    是的,只需添加一个参数int off或使用IntBuffer类即可

    void foo(int[] a,int off, int l) {
     ...
     System.out.printf("%d", a[off];  //prints 1
     ...
     ...
    }
    
    f(a,2,l);
    
    
    void foo(IntBuffer a,int l){
       System.out.printf("%d",a.get(0));
    }
    IntBuffer buffer = IntBuffer.wrap(a,2,a.length-2);
    foo(buffer,l);
    
  5. # 5 楼答案

    java中数组的底层结构的头部有一个额外的元素,表示数组的长度。因此,您的原始数组将是由JVM存储的{len, 1, 2, 3, 4, 5}。这样做是为了防止java“安全”地在数组上执行索引外操作。这也使得在java中进行指针运算几乎不可能

    要在java中执行类似的操作,通常需要使用某种Buffer类来包装数组