1
今天我注意到,在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);
}
}
很明顯的是,當函數調用它自己,它攜帶變量變量(即存儲每個面額的實際數字)和N,並將其與下一個調用進行比較,因此它們保持不變。但是,當遞歸展開(一個函數調用完成並且程序返回到最後一個)時,它會變得很有趣。現在,N的價值立即重新設定爲剛剛取消呼叫時的情況。這是幸運的,因爲這個功能依賴於這種行爲。但是,vals []數組的行爲與此不同。它保留從解除呼叫中對其所做的所有更改。這不會造成問題,因爲它在下次進入循環時進行更新。然而,我很好奇爲什麼原語和數組在Java中表現不同。此外,這種行爲在C,C++和C#中也可以預期嗎?請注意,如果N是某個數組的一部分而不是獨立的原始參數,則此函數不起作用。
發生這種情況是因爲基元是通過值傳遞的,而數組和對象是通過引用值傳遞的。它發生在所有函數上,與遞歸無關。 – Zong
不僅僅是數組,而是所有的對象(所有非原始類型)都作爲參數傳遞給目標方法,這樣就可以證明你在這裏看到的與數組相同的行爲。 – Keith
有沒有可能改變這種行爲?另外,其他語言也一樣嗎? –