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

时间:2012-06-19 18:47:22

标签: java c

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

  1. 在C中,我们可以通过参考
  2. 按值调用方法
  3. 在Java中,我们只能按值调用方法(当我们传递一个Object时,我们传递的是对象引用的值而不是对象引用本身)
  4. 在C和Java上下文中,指针和引用之间存在差异。
  5. 现在问题:

    考虑一个数组:

    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中传递数组的一种巧妙方法。

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

    foo(arr);
    

5 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

如果您的问题是关于是否可以像arr + 2那样通过指针算法来处理数组的元素,那么答案就是否定。

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

Java缺少本机切片函数(作为C中关于数组开头的隐式函数或者你在一些现代语言中使用的隐式函数)但是很容易构建自己的包装数组,索引和如果你需要它的长度。

答案 4 :(得分:0)

在C和Java中传递数组时,这个想法是一样的。

在Java中,为对象传递的所有内容都是对它们的引用,即指针。在Java中,你永远不会说:A * a = new A();你刚写A a = new A();缺乏*是不同的。否则,A的行为与指针完全相同。

原始变量按值传递。