• 沒有找到結果。

第第七七章章 函函 數數

N/A
N/A
Protected

Academic year: 2021

Share "第第七七章章 函函 數數"

Copied!
25
0
0

加載中.... (立即查看全文)

全文

(1)

第 第 七 七 章 章 函 函 數 數

本章學習目標

認識 Java 的函數

學習函數引數傳遞的方式

學習遞迴函數的撰寫

認識函數的多載

(2)

7.1 函數的基本概念

Java 的慣例是把函數稱為 method。method 可用如下的語法來定義:

public static 傳回值型態 method 名稱(型態 引數 1, 型態 引數 2,...) {

程式敘述 ; return 運算式;

}

格式7.1.1 定義method method 的主體

(3)

7.1.1 簡單的範例

app7_1 是一個簡單的 method 實例。

01 // app7_1, 簡單的範例 02 public class app7_1 03 {

04 public static void main(String args[]) 05 {

06 star(); // 呼叫 star() method

07 System.out.println("Knowledge is power");

08 star(); //呼叫 star() method 09 }

10

11 public static void star() // star() method 12 {

13 for(int i=0;i<20;i++)

14 System.out.print("*"); // 印出 20 個星號 15 System.out.print("\n"); // 換行

16 } 17 }

/* app7_1 OUTPUT---

********************

Knowledge is power

********************

---*/

main() method

star() method

(4)

star() method 被呼叫與執行的流程如下所示:

public static void star() {

}

public static void main(String args []) {

star();

star();

}

public class app7_1 {

}

(5)

7.1.2 method 的引數與傳回值

app7_2 可接收一個整數引數 n,印出 2*n 個星號後,傳回整數 2*n。

01 // app7_2, 簡單的範例--method 的引數與傳回值 02 public class app7_2

03 {

04 public static void main(String args[]) 05 {

06 int i; // 宣告整數變數 i,此變數的有效範圍僅止於 main() method 07 i=star(8); // 傳入 8 給 star(),並以 i 接收傳回的數值

08 System.out.println(i + " stars printed");

09 } 10

11 public static int star(int n) // star() method 12 {

13 int i; // 宣告整數變數 i,此變數的有效範圍僅止於 star() method 14 for(i=1;i<=2*n;i++)

15 System.out.print("*"); // 印出 2*n 個星號 16 System.out.print("\n"); // 換行

17 return 2*n; // 傳回整數 2*n 18 }

19 }

/* app7_2 OUTPUT---

****************

16 stars printed ---*/

(6)

app7_2 的 star() method 之說明如下圖所示:

11 public static int star( int n )

傳回值的型態為整數

傳入的引數為整數,引數名稱為n

(7)

app7_3 是一個計算長方形對角線長度的範例。

01 // app7_3, 計算長方形對角線的長度 02 public class app7_3

03 {

04 public static void main(String args[]) 05 {

06 double num;

07 num=show_length(7,3); // 傳入 7 與 3 兩個引數到 show_length()裡 08 System.out.println("length = "+num);

09 } 10

11 public static double show_length(int m, int n) 12 {

13 return Math.sqrt(m*m+n*n); // 傳回對角線長度 14 }

15 }

/* app7_3 OUTPUT--- length = 7.615773105863909 ---*/

(8)

7.1.3 引數是如何傳遞給 method 的?

基本資料型態的變數傳遞到 method 的方式,均是以「傳值」的方式來 進行,如下面的範例:

01 // app7_4, method 傳值的範例 02 public class app7_4

03 {

04 public static void main(String args[]) 05 {

06 int num=5;

07 add10(num); // 呼叫 add10(),並傳遞 num 08 System.out.println("in main(), num = "+num);

09 } 10

11 public static void add10(int value) 12 {

13 value=value+10; // 將 value 的值加 10 之後,設回給 value 14 System.out.println("in add10(), value = "+value);

15 } 16 }

/* app7_4 OUTPUT--- in add10(), value = 15 in main(), num = 5 ---*/

(9)

於 app7_4 中,value 與 num 的值之變化如下圖所示:

public static void main(String args[]) {

int num=5;

add10(num);

...

}

public static void add10(int value) {

value=value+10;

...

}

num 5

5 num 的拷貝

num 的拷貝指定 給變數vaule

此行敘述只會更改到 num 的 拷 貝 , 而 不 會 更 改 到 main() 裡的 num 變數 num 的值拷貝一份

value

(10)

7.2 傳遞陣列到 method 裡 7.2.1 傳遞一維陣列

app7_5 是傳遞一維陣列到 largest() 的範例。

01 // app7_5, 簡單的範例 02 public class app7_5 03 {

04 public static void main(String args[]) 05 {

06 int score[]={5,3,8,12,6,7}; // 宣告一維陣列 score

07 largest(score); // 將一維陣列 score 傳入 largest() method 08 }

09 10

11 public static void largest(int arr[]) 12 {

13 int max=arr[0];

14 for(int i=0;i<arr.length;i++) 15 if(max<arr[i])

16 max=arr[i];

17 System.out.println("largest num = "+max);

18 } 19 }

將陣列score 傳入 largest() method 裡

接收一維的整數陣列

/* app7_5 OUTPUT--- largest num = 12 ---*/

(11)

7.2.2 傳遞二維陣列

app7_6 是傳遞二維陣列的範例:

01 // app7_6, 傳遞二維陣列 02 public class app7_6 03 {

04 public static void main(String args[]) 05 {

06

07 int A[][]={{51,38,82,12,34},{72,64,19,31}}; // 定義二維陣列 08 print_mat(A);

09 } 10

11 public static void print_mat(int arr[][]) 12 {

13 for(int i=0;i<arr.length;i++) 14 {

15 for(int j=0;j<arr[i].length;j++)

16 System.out.print(arr[i][j]+" "); // 印出陣列值 17 System.out.print("\n");

18 } 19 } 20 }

將二維陣列A 傳入 print_mat() method 裡

接收二維的整數陣列

/* app7_5 OUTPUT--- 51 38 82 12 34 72 64 19 31

---*/

(12)

7.2.3 傳回陣列的 method app7_7 是傳回二維陣列的練習。

01 // app7_7, 設計傳回二維陣列的 method 02 public class app7_7

03 {

04 public static void main(String args[]) 05 {

06 int A[][]={{51,38,82,12,34},{72,64,19,31}}; // 定義二維陣列 07 int B[][]=new int[2][]; // 宣告陣列 B,並設定列數

08 B[0]=new int[5]; // 設定陣列B 第一列的行數 09 B[1]=new int[4]; // 設定陣列B 第二列的行數 10

11 B=add10(A); // 呼叫 add10(),並把傳回的值設給陣列 B 12 for(int i=0;i<B.length;i++) // 印出陣列的內容 13 {

14 for(int j=0;j<B[i].length;j++) 15 System.out.print(B[i][j]+" ");

16 System.out.print("\n");

17 } 18 }

(13)

19

20 public static int[][] add10(int arr[][]) 21 {

22 for(int i=0;i<arr.length;i++) 23 for(int j=0;j<arr[i].length;j++)

24 arr[i][j]+=10; // 將陣列元素加 10 25 return arr; // 傳回二維陣列 26 }

27 }

/* app7_7 OUTPUT-- 61 48 92 22 44 82 74 29 41

---*/

傳回二維的整數陣列

(14)

7.2.4 陣列的傳遞機制

傳遞陣列時,是以「傳參照」(pass by reference)的方式來進行。下 面的範例說明了「傳參照」和「傳值」的機制的不同。

01 // app7_8,「傳參照」的範例 02 public class app7_8 03 {

04 public static void main(String args[]) 05 {

06 int A[]={1,2,3,4,5};

07

08 square(A); // 呼叫 square(),並傳遞陣列 A 09

10 System.out.println("呼叫 square() method 之後...");

11

12 for(int i=0;i<A.length;i++) // 印出陣列的內容 13 System.out.print(A[i]+" ");

14

15 System.out.println();

16 } 17

18 public static void square(int arr[]) 19 {

(15)

20 for(int i=0;i<arr.length;i++)

21 arr[i]=arr[i]*arr[i]; // 將陣列的元素值平方 22 }

23 }

/* app7_8 OUTPUT--- 呼叫square() method 之後...

1 4 9 16 25

---*/

(16)

square() method 的呼叫過程可用下圖來表示:

public static void main(String args[])

{

int A[]={1,2,3,4,5};

square(A);

...

}

public static void square(int arr[]) {

for(int i=0;i<arr.length;i++) arr[i]=arr[i]*arr[i];

}

A 的參照

A 的參照 將參照拷貝

將參照的拷貝 指定給arr

因為陣列A 的參照與 arr 均指向同一 個陣列實體,因而若更改了arr 的內 容,陣列A 的內容也隨之被更改

A 參照的拷貝 1

2 3 4 5 A

此行會將陣列A 的參照拷貝一 份,然後把拷貝的這份傳遞給 square()。注意是拷貝參照,而 不是拷貝陣列的實體

arr

(17)

7.3 遞迴

遞迴就是 method 本身呼叫自己。

階乘函數(factorial function, n ! )便可利用遞迴的方式來完成:

1 2 ; 1

fac( )

1; 0

n n

n n

× × × ≥

= ⎨ ⎧ ⎩ =

L (非遞迴的運算方式)

fac( 1) ; 1 fac( )

1 ; 0

n n n

n n

× − ≥

= ⎨ ⎧ ⎩ = (遞迴的運算方式)

(18)

以階乘函數來說明如何撰寫遞迴 method。

01 // app7_9, 簡單的遞迴 method 02 public class app7_9

03 {

04 public static void main(String args[]) 05 {

06 System.out.println("1*2*..*4 = "+fac(4));

07 }

08 public static int fac(int n) // fac() method 09 {

10 if(n==0) // 設定終止條件 11 return 1;

12 else

13 return n*fac(n-1); // 遞迴計算 14 }

15 }

/* app7_9 OUTPUT-- 1*2*...*4=24

---*/

(19)

計算 fac(4) 4 3 2 1 24 = × × × = ,其遞迴計算的過程如下圖所示:

step 1

fac(4) fac(4)

4* fac(3) 4* fac(3)

3* fac(2) 3* fac(2)

2* fac(1) 2* fac(1)

1* fac(0) 1* fac(0)

2*1=2 2*1=2 3*2=6 3*2=6 4*6=24 4*6=24 return 24 return 24

step 2

step 3

step 4

step 5

step 7 step 8 step 9 step 10

fac(0)=1 fac(0)=1

1*1=1 1*1=1 step 6

(20)

7.4 method 的多載

多載(overloading)可將功能相似的 method,以相同名稱命名,編譯

器會根據引數的個數與型態,自動執行相對應的 method。

(21)

下面的程式碼是說明引數型態不同的函數多載:

01 // app7_10,引數型態不同的函數多載 02 public class app7_10

03 {

04 public static void main(String args[]) 05 {

06 int a=5, b[]={1,2,3,4};

07 show(a); // 將整數 a 傳遞到 show()裡

08 show(b); // 將整數陣列 b 傳遞到 show()裡 09 }

10

11 public static void show(int i) // 定義 show(),可接收整數變數 12 {

13 System.out.println("value= "+i);

14 } 15

16 public static void show(int arr[]) // 定義 show(),可接收整數陣列 17 {

18 System.out.print("array=");

19 for(int i=0;i<arr.length;i++) 20 System.out.print(" "+arr[i]);

21 System.out.println();

22 } 23 }

/* app7_10 OUTPUT--- value= 5

array= 1 2 3 4

---*/

(22)

多載會根據 method 的引數來判別哪一個 method 會被呼叫,而不是根 據 method 的傳回值。

某個 method 的定義如下:

int func(int a, int b) // 傳回值型態為 int 的 method { ....

}

這個函數原型會與下面 method 的定義相衝突而產生錯誤:

long func(int a, int b) // 傳回值型態為 long 的 method { ....

}

(23)

app7_11 是利用引數個數的不同來多載 method 的範例。

01 // app7_11, 利用引數個數的不同來多載 method 的範例 02 public class app7_11

03 {

04 public static void main(String args[]) 05 {

06 star(); // 呼叫 11~14 行所定義的 star() method 07 star(7); // 呼叫 16~21 行所定義的 star() method 08 star('@',9); // 呼叫 23~28 行所定義的 star() method 09 }

10

11 public static void star() // 沒有引數的 star() method 12 {

13 star(5); // 呼叫 16~21 行所定義的 star(),並傳入整數 5 14 }

15

16 public static void star(int n) // 有一個引數的 star() method 17 {

18 for(int i=0;i<n;i++) 19 System.out.print("*");

20 System.out.println();

21 } 22

(24)

23 public static void star(char ch, int n) // 有兩個引數的 star() method 24 {

25 for(int i=0;i<n;i++) 26 System.out.print(ch);

27 System.out.println();

28 } 29 }

/* app7_11 OUTPUT---

*****

*******

@@@@@@@@@

---*/

(25)

參考文獻

相關文件

是以法國物理學家 Augustin Fresnel 命名的。.

而此時,對於相對成長率為 k 的族群,其滿足族群成長模型 的解為指數函數 Ce kt ,此時的 k 便是指數中時間 t

如果函數是由基本函數所組成,至少需要注意:分式函 數分母會等於 0

編號 申請單位 計畫名稱 核定數 實支數 賸餘數

相對應的,由於這些函數可以跟雙曲線上的點做對應,所以 稱為雙曲函數,其中主要的奇組合稱為 hyperbolic sine 雙曲 正弦函數,偶組合稱為

我們已經學過了一元一次方程式與二元一次方程式,在本章中,我們將學習一元二次

對於給定的一個 x 值,經過某一對應方式後得到「唯一」的 y 值,這種對應方式我們稱 為函數,其中 x 是自變數,y 是應變數。. 而在表

前一章我們學過了一次函數,本章將繼續延伸到二次函數。二次函數的函數圖形為拋