1. 程式人生 > >java 11:陣列作為函式引數,陣列做為函式返回值

java 11:陣列作為函式引數,陣列做為函式返回值

1 陣列作為引數

我們可以將陣列作為引數,傳入到函式中,其實就像我們main函式中 public void main(String [] args){};就是用陣列作為函式引數;

又如,

  1. publicclass ArrayPar  
  2. {  
  3. publicstaticvoid printArray(int [] array)  
  4.     {  
  5. for(int i=0;i<array.length;i++) 
  6.             System.out.print(array[i]+"  ");  
  7.     }  
  8. }  
我們可以這樣呼叫 ArrayPar.printt(new int[ ]{3,2, 5,67});呼叫陣列

這裡的new int[ ]{3,2,5,67};他也是一種建立陣列的方法,只是這種方法創建出來的陣列是沒有名字的,所以叫匿名陣列。很多時候在只使用一次的時候可以使用匿名陣列的方法法,類似的還有匿名類。

Java uses pass-by-value to pass arguments to a method. There are important differences
between passing the values of variables of primitive data types and passing arrays.
■ For an argument of a primitive type, the argument’s value is passed.
■ For an argument of an array type, the value of the argument is a reference to an array;
this reference value is passed to the method. Semantically, it can be best described as
pass-by-sharing, i.e., the array in the method is the same as the array being passed.
So if you change the array in the method, you will see the change outside the
method.

java 使用值傳參(pass_by_value)的方式來傳遞函式引數,只是值傳遞方式在處理原始資料型別引數與引用型別引數時候有不同,如果一個引數是原始資料型別,那麼引數變數的值傳遞進去。如果是引用型別,是傳進了引用變數的值(也就是說,只是將指向資料的引用的值給傳進去了,也就是被呼叫的函式新建的空間放的是這個引用的值,那麼也就是也指向了陣列存在的記憶體),所以同樣是值傳遞,引用型別的傳入的當然是引用變數的值,指向了同一陣列,那麼函式內對陣列進行的修改在函式退出後依舊是有效的。

例子:

  1. publicclass ArrayPar  
  2. {  
  3.     publicstaticvoid main(String [] args)  
  4.     {  
  5.         int x=1;  
  6.         int y[]={1,2,3};  
  7.         change(x,y);  
  8.         System.out.println("x="+x+",y[0]="+y[0]);  
  9.     }  
  10.     publicstaticvoid change(int num,int [] array)  
  11.     {  
  12.         num=100;  
  13.         array[0]=100;  
  14.     }  
  15. }  

圖形表示:


這裡同時注意一下,當我們用new 以及malloc這些的記憶體空間是在堆上heap,而像我們被呼叫的函式中使用的這些變數等在棧上。在呼叫changes時候,x的值被傳入,在被呼叫的函式中重新開闢一個空間來放這個基本資料型別引數,但是int [ ] y ,將y傳入其實就是傳入了引用,在被呼叫的函式的棧上只會開闢一個空間來存放這個引用,所以被呼叫的函式與呼叫者 中兩個引用指向堆上同一塊記憶體。

2 陣列做為函式返回值

  1. publicstatic<span style="color:#ff0000;"int []</span> reverse(int [] array)  
  2. {  
  3.     int [] result=newint[array.length]  
  4.     for(int i=0;i<array.length;i++)  
  5.     {  
  6.         result[i]=array[lenght-i];  
  7.     }  
  8.     return result;
  9. }  
在將陣列作為函式返回值時候如上紅色標出的,就是在函式名字前加上返回值型別是int [ ] 表示返回一個int型陣列,在函式體內最後返回是result這樣的函式引用。

Case Study: Counting the Occurrences of Each Letter

write a program to count the occurrences of each letter in an random array of  lower  characters.

那麼我們可以怎麼做呢?

1)首先是要產生一個隨機char陣列  creatArray();(是否記得前邊說過產生[a,a+b)之間的一個隨機數 為  a+Math.random()*b,是否記得我們建立過獲取任意字元的一個類?)

2) 建立一個數組 int [ ] count,長度26,準備來存放各個字母的計數

3)對陣列進行迴圈 , 每讀取一個字母ch,則 count[ch-'a']++;

  1. class RandomChar  
  2. {  
  3.     publicstaticchar getRandomChar(char ch1,char ch2)  
  4.     {  
  5.         return (char)(ch1+Math.random()*(ch2-ch1+1));  
  6.     }  
  7.     publicstaticchar getLowerCaseLetter()  
  8.     {  
  9.         return getRandomChar('a','z');  
  10.     }  
  11.     publicstaticchar getUpperCaseLetter()  
  12.     {  
  13.         return getRandomChar('A','Z');  
  14.     }  
  15.     publicstaticchar getDigitalLetter()  
  16.     {  
  17.         return getRandomChar('0','9');  
  18.     }  
  19.     publicstaticchar getRandomLetter()  
  20.     {  
  21.         return getRandomChar('\u0000','\uFFFF');  
  22.     }  
  23. }  
  24. publicclass CountOccur  
  25. {  
  26.     publicstaticvoid main(String [] args)  
  27.     {  
  28.          char [] array=CreateArray();  
  29.          int [] count = newint[26];  
  30.          for(int i=0;i<array.length;i++)  
  31.          {  
  32.              count[array[i]-'a']++;  
  33.          }  
  34.          for(int i=0;i<count.length;i++)  
  35.          {  
  36.             System.out.print((char)(i+'a')+": "+count[i]+"    ");  
  37.             if((i+1)%10==0) System.out.println();  
  38.          }  
  39.     }  
  40.     //產生一個100個元素的小寫隨機陣列
  41.     publicstaticchar[] CreateArray()  
  42.     {  
  43.         char [] a=newchar[100];  
  44.         for(int i=0;i<a.length;i++)  
  45.         {  
  46.             a[i]=RandomChar.getLowerCaseLetter();  
  47.         }  
  48.         return a;  
  49.     }  
  50. }  



3 可變長度引數列表

You can pass a variable number of arguments of the same type to a method. The parameter in
the method is declared as follows:
typeName... parameterName
In the method declaration, you specify the type followed by an ellipsis Only one vari-
able-length parameter may be specified in a method, and this parameter must be the last para-
meter. Any regular parameters must precede it.
Java treats a variable-length parameter as an array. You can pass an array or a variable
number of arguments to a variable-length parameter. When invoking a method with a variable
number of arguments,
Java creates an array and passes the arguments to it

我們可以傳遞型別相同,但個數可以變化的引數到函式中,如果有這個需求的話,這時候我們只需要在形式引數中使用 typename...parameterName就可以達到這個目的,要注意,在這裡宣告的該變長引數必須是最後一個引數,任何常規引數必須在他之前,也就是說你可以有 MethodName(char b, double c, int ... nums) 這樣的形式即int ... nums必須在最後一個位置,你不能將int ... nums 宣告在引數引數列表的非最後位置。

java將可變長引數當做陣列對待。可以將一個數組或者可的引數個數傳遞給該引數(注意,我們這裡說該引數就是 typeName ... parameterName這整個結構),無論哪種形式,java會建立一個數組並把引數傳給他,注意這裡體會原文說的When invoking a method with a variable
number of arguments, java Create an array and passes the arguments to it
,也就是說,如果你是傳入幾個變長的變數,那麼在呼叫時候java先將建立一個數組來裝這幾個實際引數,然後再執行呼叫的函式,如果本身我們傳入一個數組,其實他並不會建立一個新的陣列來裝,還是一樣像上面指向了已經分配的陣列空間,所以在被呼叫的函式中對陣列的改變在退出時候還是有效的(這是我用例子試了下體會到的)

  1. publicclass VariablePar  
  2. {  
  3.     publicstaticvoid main(String [] args)  
  4.     {  
  5.         int array[]={1,4,7,2,0};  
  6.         System.out.println("max="+findMax(array));  
  7.         ifChange(array);  
  8.         System.out.println("array[0]="+array[0]);  
  9.         ifChange(1,45,33);  
  10.     }  
  11.     publicstaticint findMax(int ... nums)  
  12.     {  
  13.         if(nums.length==0)   
  14.         {  
  15.             System.out.println("No argumment passed");  
  16.             return -1;  
  17.         }  
  18.         int max=nums[0];  
  19.         for(int i=1;i<nums.length;i++)  
  20.         {  
  21.             if(max<nums[i]) max=nums[i];  
  22.         }  
  23.         return max;  
  24.     }  
  25.     //測試這裡究竟是新建立一個數組還是相當於把引用傳進來而已
  26.     publicstaticvoid ifChange(int ... nums)  
  27.     {  
  28.         nums[0]=100;  
  29.     }  
  30. }  
這裡,我們從findMax中看到,他不用先說明 什麼就可以直接使用nums.lenght 說明確實java是完全將這型別的引數當做一個數組來處理了,二在ifChange中,我們看到輸出的是array[0]=100,說明我們在呼叫ifChange(array)時候並不是重新建立一個新的陣列,而是還是一樣像前邊的傳入了引用,被呼叫者還是指向了相同的陣列空間。但是在ifChage(1,45,33)這個呼叫時候,java就會先new int[ ]{1,45,33} 這樣,然後形參nums再指向它,其實這樣返回後應該就不會改變了1的值吧?