繁体   English   中英

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

[英]Passing array as an argument: C and 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);

是的,只需添加一个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);

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

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

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

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

Java缺乏本机切片功能(就像C中关于数组开始的隐式函数或几种现代语言中的显式函数),但是很容易构建自己的类,该类包装数组,索引和长度你需要它。

当您使用C和Java传递数组时,想法是相同的。

在Java中,为对象传递的所有内容都是对其的引用,即指针。 在Java中,您永远不会说:A * a = new A(); 您只需编写A a = new A(); 缺少*是区别。 否则,A的行为完全类似于指针。

基本变量按值传递。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM