0

在我问我的问题之前,我会指出我知道:

  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
  ...
}

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

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

foo(arr);
4

5 回答 5

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);
于 2012-06-19T18:56:51.850 回答
1

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

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

于 2012-06-19T18:51:46.263 回答
1

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

要在 java 中做这样的事情,你通常会使用某种Buffer类来包装你的数组。

于 2012-06-19T18:52:26.437 回答
0

Java 缺少原生切片函数(如 C 中关于数组开头的隐式切片函数或在一些现代语言中的显式切片函数),但很容易构建自己的包含数组、索引和长度的类,如果你需要它。

于 2012-06-19T18:50:05.300 回答
0

当您在 C 和 Java 中传递数组时,这个想法是相同的。

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

原始变量按值传递。

于 2012-06-19T18:50:21.823 回答