将数组作为参数传递:C和Java
在我提问之前,我会注意到我知道:
- 在C语言中,我们可以通过值调用方法,也可以通过引用调用方法
- 在Java中,我们只能按值调用方法(当我们传递对象时,我们传递的是对象引用的值,而不是对象引用本身)
- 在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);
# 1 楼答案
Java缺少本机的切片函数(比如C中关于数组开头的隐式切片函数,或者几种现代语言中的显式切片函数),但是如果需要,可以很容易地构建自己的类来包装数组、索引和长度
# 2 楼答案
在C和Java中传递数组时的想法也是一样的
在Java中,所有传递给对象的都是对它们的引用,即指针。在Java中,你永远不会说:A*A=newa();你只需要写一个A=新的A();缺少*就是区别。否则,A的行为与指针完全相同
原语变量按值传递
# 3 楼答案
如果您的问题是关于是否可以通过执行
arr + 2
中的指针算法来寻址数组的元素,那么答案是否定的但是,通过传入数组和要开始读取数组的位置,可以实现相同的效果
# 4 楼答案
是的,只需添加一个参数
int off
或使用IntBuffer
类即可# 5 楼答案
java中数组的底层结构的头部有一个额外的元素,表示数组的长度。因此,您的原始数组将是由JVM存储的
{len, 1, 2, 3, 4, 5}
。这样做是为了防止java“安全”地在数组上执行索引外操作。这也使得在java中进行指针运算几乎不可能要在java中执行类似的操作,通常需要使用某种
Buffer
类来包装数组