我今天指出,在Java中,当数组和基元作为递归函数的一部分时,它们的行为会有所不同。例如,考虑下面的递归代码,用于查找整数(N)可以用数组(denom [])给出的不同面额的硬币表示的方式的数量:
public static void printAll(int ind, int[] denom,int N,int[] vals){
if(N==0){
System.out.println(Arrays.toString(vals));
return;
}
if(ind == (denom.length))return;
int currdenom = denom[ind];
for(int i=0;i<=(N/currdenom);i++){
vals[ind] = i;
printAll(ind+1,denom,N-i*currdenom,vals);
}
}
很明显,当函数调用自身时,它携带变量vars(即存储每个面额的实际数字)和N携带到下一个调用中,因此它们保持不变。但是,当递归展开(一个函数调用完成并且程序返回到最后一个)时,它会变得有趣。现在,N的值立即重置为刚刚解开的呼叫时的状态。这很幸运,因为这个功能依赖于这种行为。但是,vals []数组的行为与此不同。它保留了从未解除的呼叫中对其进行的所有更改。这不会在这里造成问题,因为它在下次进入循环时会更新。但是,我很好奇为什么原语和数组在Java中表现不同。此外,在C,C ++和C#中也可以预期这种行为吗?请注意,如果N是某个数组的一部分而不是独立的原始参数,则此函数将不起作用。