Microsoft PowerPoint - SE7ch06.ppt
|
|
|
- 湘 枚
- 9 years ago
- Views:
Transcription
1 第六章 函式 (Method; ; 方法 ) 課前指引在設計程式時, 我們會將一個較大的程式切割為許多個子功能, 每個子功能或許可以再切割為數個更小的功能, 一直將功能分解到每個小功能皆可以很輕易地由簡短的程式加以完成為止 我們通常將這些小功能獨立寫成一個 函式, 或者將程式中常常重複的程式區塊獨立出來寫成一個 函式, 當程式需要運用該功能時, 就可以直接呼叫函式, 使得主要程式的長度變短而有助於日後的維護 在物件導向程式設計中, 這些函式 (function) 被稱為方法 (method), 並且隸屬於某一個類別, 在 Java 中, 這些方法又可以分為兩種, 一種是可以由類別直接執行的靜態方法 (static method), 另一種則是必須由類別產生物件實體後, 由物件執行的方法 章節大綱 6.1 認識函式 6.2 自行定義函式 6.3 好用的亂數函式 6.4 引數串列與引數傳遞 6.7 main 函式的參數串列 6.8 函式的 final 參數 6.9 遞迴函式 6.10 多載 (overloading) 6.5 回傳陣列 6.6 搜尋演算法 補充 6.11 本章回顧 備註 : 可依進度點選小節備註可依進度點選小節
2 6.1 認識函式 函式在物件導向中, 由於隸屬於某一類別, 故稱為成員函式 (member function), 又稱為方法 (method) 因此在本書中, 我們可能以函式 成員函式 方法 成員方法等名詞來解說, 其實指的都是 method 什麼是函式 Java 提供的函式功能與數學的函數類似 在數學函數中, 我們輸入函數的參數並經過函數處理後, 將可以得到函數的輸出結果 在 Java 的函式中, 同樣地也是如此, 我們必須傳遞引數 (Argument) 給函式處理, 經過函式的處理之後, 可以獲得一個輸出結果 ( 即函式回傳值 ) 例如 :valueof() 就是隸屬於 String 類別, 用來將數值轉換為字串的函式 兩者的比較如下圖示意 4
3 6.1.1 什麼是函式 圖 6-1 數學函數與 Java 函式比較圖 Java 的函式與數學函數類似, 在數學函數中, 我們會規定該數學函數的定義域範圍, 例如 :x,y 為任意正數同樣地, 我們也必須限制 Java 函式輸入引數的資料型態, 例如 :i 必須為 int 型態 比較不一樣的地方是在 Java 函式回傳值的資料型態方面, 我們必須在函式宣告時就定義回傳值的資料型態, 同時,Java 也允許函式沒有回傳值 函式的優點與特性 程式語言的函式雖然與數學的函數有些類似, 但設計的目的則略有不同程式語言的函式可以視為 一群敘述的集合, 因此我們常常會將某些經常使用的敘述群, 直接用一個函式加以包裝, 然後在需要使用時, 直接呼叫該函式, 如此便可以有效重複利用程式碼 Java 函式的特點整理如下 : (1)Java 的函式隸屬於某一個類別, 函式擁有屬於自己的名稱, 除非透過多載 (overload) 技術, 否則不允許宣告兩個相同名稱的函式 (2) 函式內宣告的變數為 區域變數, 換句話說, 在不同函式內可以使用相同的變數名稱, 因為該變數只會在該函式中生效 6
4 6.1.2 函式的優點與特性 (3) 函式最好具有特定功能 ( 並以該功能來命名函式 ), 並且函式的程式碼應該越簡單越好, 如此才能夠提高程式的可讀性並有利於除錯與日後的維護 (4) 對於發展大型類別而言, 將物件可能使用的功能製作為方法 ( 即函式 ), 可以交由許多的程式設計師分工撰寫各個方法, 如此一來, 可以加快類別的開發速度, 不過在切割功能及實際撰寫方法之前, 必須討論出一定的規格, 以免發生不協調的狀況 (5) 類別內撰寫的函式分為 static method 與一般 method, 其中,static method 內的敘述只能呼叫 static method 呼叫函式的執行流程 我們可以直接使用別人已經撰寫好的函式, 只要知道該函式所屬之類別, 透過 import 引入該類別即可 例如 : 我們只要先引入 Java 提供的 java.lang.string 類別, 就可以直接使用 valueof( ) 函式, 而不必自行撰寫 valueof( ) 函式 如果該函式被宣告為 static, 則不用產生物件即可使用 當主程式呼叫函式時程式的控制權將會轉移到相對應的函式開頭處, 然後執行函式中的程式碼函式的程式碼執行完畢後, 程式控制權將重新回到主程式碼 ( 呼叫敘述 ) 的下一個敘述, 繼續往下執行 8
5 6.1.3 呼叫函式的執行流程 圖 6-2 函式呼叫與返回示意圖 ( 程式控制權的轉移 ) 觀念範例 6-1 : 藉由範例說明函式呼叫與返回的程式流程控制權之轉移 範例 6-1:ch6_01.java( 隨書光碟 myjava\ch06\ch6_01.java) 呼叫函式的執行流程 /* 檔名 :ch6_01.java 功能 : 呼叫 static method */ package myjava.ch06; import java.lang.*; import java.lang.math; public class ch6_01 // 主類別 public static void main(string args[]) double i=7.0,j=4.0; double pownum,lognum; pow,log10 所屬類別, 由於屬於 java.lang.* 類別庫, 故可省略 pownum=math.pow(i,j); System.out.println(i + " 的 " + j + " 次方 =" + pownum); lognum=math.log10(pownum); System.out.println(powNum + " 取 10 的對數 =" + lognum); 10
6 6.1.3 呼叫函式的執行流程 執行結果 : 範例說明 : 7.0 的 4.0 次方 = 取 10 的對數 = (1) 第 5 行 : 引入類別 java.lang.math, 該類別中包含有 pow( ) 與 log10( ) 兩個 static method 這兩個 static method 的宣告原型如下 : 所屬類別 :java.lang.math 語法 :static double pow(double a, double b) 功能 : 回傳 a 的 b 次方 所屬類別 :java.lang.math 語法 :public static double log10(double a) 功能 : 回傳 a 的對數 ( 以 10 為底 ) 呼叫函式的執行流程 範例說明 : (2) 第 14 行 : 呼叫 pow 函式, 幫我們計算 i 的 j 次方, 回傳值由 pownum 接收 (3) 第 16 行 : 呼叫 log10 函式, 幫我們計算 pownum 的對數 ( 以 10 為底 ), 回傳值由 lognum 接收 (4) 由於第 4 行已經引入所有 java.lang 的所有類別, 因此, 第 5 行可以省略, 不過由於要提醒這兩個函式的類別名稱, 故我們仍將之保留 事實上,java.lang.Math 並不會被引入兩次, 因為編譯器會替我們檢查是否有重複引入的類別 (5) 整個程式的流程如下圖所示 12
7 6.1.3 呼叫函式的執行流程 圖 6-3 範例 6-1 的程式流程 自行定義函式 除了使用 Java 或其他廠商開發的類別函式, 我們也可以自行發展類別與函式 由於目前我們只學習到主類別, 因此本章內容以發展主類別的函式為主 至於其他類別的函式則由下一章開始介紹 14
8 6.2.1 函式定義 在使用函式之前, 必須先定義函式內容 ( 也就是函式的定義 ) 函式的內容決定了該函式究竟提供了什麼樣的服務 定義主類別其他函式的語法 [ 封裝等級 ] static 回傳值型態 method 名稱 ( 資料型態參數 1, 資料型態參數 2, ) 函式主體 ( 程式碼 ) [return ;] 函式定義 語法說明 : (1) 封裝等級 : 下一章會進行介紹, 此處使用 public 宣告封裝等級即可 (2)static 關鍵字 : 由於主函式被宣告為 static, 而 static method 內的程式碼只能呼叫 static method, 因此為了要讓主函式 main 呼叫, 故必須宣告為 static method (3) 回傳值型態 : 若函式沒有回傳值, 此時可將回傳值型態宣告為 void (4) 參數群 : 1.method 名稱小括號內則是參數群, 每宣告一個輸入參數, 都必須清楚地宣告該參數的資料型態, 也同時宣告該輸入參數在函式中所代表的變數名稱 而參數的資料型態將會限制住傳入引數之資料型態 2. 參數的命名規則與一般變數的命名規則相同 3. 輸入參數在函式主體內屬於合法的資料變數, 也就是說, 我們不用在函式主體內宣告這些參數, 就可以直接將這些輸入參數當作已宣告的變數使用 4. 若無引數需要傳遞, 則參數列可以為空白, 但 ( ) 不可省略 16
9 6.2.1 函式定義 (5)return 敘述 : 1. 具有回傳值的函式, 在函式主體內應該包含一個以上的 return 敘述, 以便傳回資料 不具回傳值的函式則可以沒有 return 敘述 2. 具有回傳值的函式, 其 return 後面應該接上與回傳值相容資料型態的常數 變數或運算式 (6) 合法的函式定義範例 函式定義範例 public static void showwelcome(int print_times) for(int a=1;a<=print_times;a++) System.out.println (" 您好, 歡迎光臨 "); 解說 1. 您可以在函式主體內使用輸入參數 print_times 2. 函式無回傳值 函式定義 函式定義範例 解說 public static int Mul(int a,int b) int result; result = a*b; return result; 1. 您可以在函式主體內使用輸入參數 a,b 2. 函式回傳值的資料型態為 int 3. 使用 return 回傳資料,result 為 Mul 函式的回傳值 4. return 敘述執行完畢, 控制權將立刻返回原呼叫函式的下一個敘述 public static double Add(double a,double b) return (a+b); 1. 您可以在函式主體內使用輸入參數 a,b 2. 函式回傳值的資料型態為 double 3. 使用 return 回傳資料,(a+b) 運算式的結果為 Add 函式的回傳值 4. 執行完畢 return 敘述, 控制權將立刻返回原呼叫函式的下一個敘述 18
10 延伸學習 : 引數與參數在第 2 章中, 我們提及到 Java 有四種變數, 也就是實體變數 (Instance Variables) 類別變數 (Class Variables) 區域變數 (Local Variables) 參數 (Parameters), 其中參數與引數是相互對應的 通常, 一個程式語言如果同時出現 Parameter 與 Argument 兩詞, 則 Argument 代表的是呼叫方傳遞的值, 並且它必須是單向的, 也就是不會受到被呼叫方的影響 而被呼叫方宣告的對應變數則稱為 Parameter, 它是可以改變的值 ( 因為對被呼叫方來說, 它是一個變數 ) 換句話說, 在 Java 的函式定義列中宣告的變數稱為參數 (Parameter) 而呼叫函式敘述中小括號內出現的叫做引數 (Argument) 在不同場合中, 這些名詞有不同的稱呼, 因此, 您可能在不同的書籍中, 看到不同的名稱 我們將之整理如下, 為了避免讀者混淆, 本書將只使用引數與參數來區別兩者 Java 語言 /C 語言 程式語言 在呼叫敘述小括號內引數 (argument) 實參數 (actual parameter) 在被呼叫函式定義或宣告第一列 參數 (parameter) 實引數 (actual argument) 正式引數 (formal argument) 正式參數 (formal parameter) 在本書中, 還有另一個名詞命令列引數, 則是代表在 Console Mode 環境中, 使用者輸入給主函式的資料項目 函式呼叫 函式經由定義後, 必須透過函式呼叫才能實際應用該函式 函式呼叫可以視為一種控制權轉移的敘述 當程式執行過程中, 遇到函式呼叫時, 控制權將被轉移到被呼叫函式的起始點, 並執行該函式的程式碼 ( 即函式定義 ), 當這些程式碼被執行完畢後 ( 或遇到 return 敘述時 ), 將會把控制權再交還給原來發生函式呼叫的程式執行點, 繼續執行下一個敘述 20
11 6.2.2 函式呼叫 在 Java 中, 呼叫端與被呼叫端若隸屬同一類別, 則呼叫函式的語法如下 : 語法 1 ( 函式無回傳值 ): method 名稱 ( 傳入引數串列 ); 語法 2 ( 函式有回傳值 ): 變數 = method 名稱 ( 傳入引數串列 ); 語法說明 : (1) 呼叫敘述與被呼叫函式間若無資料需要傳遞, 則只需要使用 method 名稱 (); 來呼叫函式即可 否則, 必須要依照函式宣告的參數個數與資料型態一一輸入對應的引數 (2) 若函式有回傳值, 則可以使用一個相容資料型態的變數來接收這個函式回傳值 函式呼叫 (3) 函式呼叫敘述必須與函式宣告的名稱相同, 但引數與參數的名稱可以不同 若呼叫者 (Caller;Calling Program) 有資料要傳遞給被呼叫者 (Callee;Called Program), 則必須藉由傳入引數串列將資料傳遞給函式的參數, 並且 傳入引數串列 的傳入變數會由 函式定義的參數串列 的相對參數來接收, 其順序 個數 資料型態必須相同 ( 不會做自動轉型 ) 但引數名稱可以與參數名稱不同 22
12 6.2.2 函式呼叫 如下圖示意 :( 圖中 3.14 必須指定為 float 型態的 3.14f, 否則會被視為 double, 而由於不會自動轉型, 故會發生錯誤 ) 圖 6-4 引數與參數的對應 函式呼叫 觀念範例 6-2 : 不使用 Math 類別的 pow 函式, 自行製作一個函式 ( power 函式 ), 功能為計算 X n (X 為 double 型態 n 為 int 型態 ) 範例 6-2:ch6_02.java( 隨書光碟 myjava\ch06\ch6_02.java) /* 檔名 :ch6_02.java 功能 : 定義, 呼叫函式 */ package myjava.ch06; import java.lang.*; import java.io.console; public class ch6_02 // 主類別 public static void main(string args[]) int k; double Ans; Console console=system.console(); System.out.print(" 計算 3.5 的 k 次方? 請輸入 k="); k=integer.parseint(console.readline()); Ans=power(3.5,k); System.out.println("3.5 的 " + k + " 次方 =" + Ans); 函式呼叫 24
13 6.2.2 函式呼叫 public static double power(double X,int n) int i; double powerxn=1; for(i=1;i<=n;i++) powerxn=powerxn*x; return powerxn; 函式定義 執行結果 : 計算 3.5 的 k 次方? 請輸入 k=5 3.5 的 5 次方 = 函式呼叫 範例說明 : (1) 第 21~28 行 :power 函式的定義, 用來計算 X n 回傳值的資料型態是 double, 接受兩個傳入引數, 資料型態分別是 double,int, 而第 27 行 return 後面的變數 powerxn 是回傳值 (2) 第 17 行 : 呼叫 power 函式, 傳入的引數為 3.5,k, 與函式定義的參數名稱不相同, 其實這並不重要, 只要傳入符合資料型態的數值或變數即可 ( 您也可以將引數與參數名稱設為相同, 但即使如此, 這兩個仍是不同的變數, 我們將在後面介紹傳值呼叫時詳加說明 ) 使用 Ans 變數來存放函式回傳值 26
14 6.2.2 函式呼叫 (3) 函式呼叫之引數傳遞與回傳值如下圖 圖 6-5 範例 6-2 的函式呼叫與回傳值 函式呼叫 實用及觀念範例 6-3 : 製作三個函式 (Odd Even TotalSum 函式 ), 功能分別為計算奇數和 偶數和 整數和 ( 其中的整數和請使用奇數和與偶數和之函式 ) 範例 6-3:ch6_03.java( 隨書光碟 myjava\ch06\ch6_03.java ) /* 檔名 :ch6_03.java 功能 : 函式應用 */ package myjava.ch06; import java.lang.*; import java.io.console; public class ch6_03 // 主類別 public static void main(string args[]) int n,sum; char addchoice; Console console=system.console(); System.out.print(" n=? 請輸入 n="); n=integer.parseint(console.readline()); System.out.print(" 請問要做奇數和 (O), 偶數和 (E), 還是整數和 (I)?"); System.out.print(" 請選擇 :"); addchoice=console.readline().charat(0); 28
15 6.2.2 函式呼叫 switch(addchoice) case 'O': sum=odd(n); break; case 'E': sum=even(n); break; case 'I': sum=totalsum(n); break; default: System.out.println(" 選擇錯誤 "); return; System.out.println(" 總和為 " + sum); public static int odd(int U) int i,total=0; for(i=1;i<=u;i++) if(i%2 == 1) total = total + i; return total; Odd 函式的定義, 用來計算 U 的奇數和 (total 是回傳值 ) 函式呼叫 public static int even(int U) int i,total=0; for(i=1;i<=u;i++) if(i%2 == 0) total = total + i; return total; Even 函式的定義, 用來計算 U 的偶數和 (total 是回傳值 ) public static int totalsum(int U) return odd(u)+even(u); 透過呼叫其他函式來完成這個函式的功 能, 可提高程式碼的再利用性 執行結果 : n=? 請輸入 n=10 請問要做奇數和 (O), 偶數和 (E), 還是整數和 (I)? 請選擇 :I 總和為 55 30
16 6.2.2 函式呼叫 範例說明 : (1) 第 53~56 行 :totalsum 函式的定義, 用來計算 U 的整數和 其中呼叫了 odd 及 even 函式, 幫忙做奇數和與偶數和, 合起來就是整數和 ( 函式應盡量重覆使用以減少程式碼 ) (2) 第 21~31 行 : 依據不同的選擇, 決定呼叫不同的函式, 完成不同的功能 請特別注意, 當使用者輸入非 O E I 時, 將會執行 default 的程式, 使用 return 結束 main( ) 的執行, 所以此時第 32 行不會被執行 這說明了 return 不但具有回傳值的功用, 也同時會將控制權交回給呼叫方 ( 在本例中, 會將控制權交還給 JVM), 中斷函式的執行 n=? 請輸入 n=10 請問要做奇數和 (O), 偶數和 (E), 還是整數和 (I)? 請選擇 :A 選擇錯誤 函式呼叫 (3) 假設我們輸入的是 10 與 O, 則整個程式的執行流程如下 : 圖 6-6 範例 6-3 的程式執行流程 ( 輸入 10 與 O ) 32
17 6.2.2 函式呼叫 實用範例 6-4 : 製作階層函式 (factorial 函式 ), 功能為計算某一正整數的階層 k! 並利用該函式求出的值,m n 為任意正整數, 範例 6-4:ch6_04.java( 隨書光碟 myjava\ch06\ch6_04.java) /* 檔名 :ch6_04.java 功能 : 函式應用 */ package myjava.ch06; import java.lang.*; import java.io.console; public class ch6_04 // 主類別 public static void main(string args[]) int m,n; long ans; Console console=system.console(); long temp[]=new long[3]; 執行結果 求排列組合 C(m,n) m = 10 n = 8 C(10,8)= 函式呼叫 範例說明 37 : System.out.println(" 求排列組合 C(m,n)"); System.out.print("m = "); m=integer.parseint(console.readline()); System.out.print("n = "); n=integer.parseint(console.readline()); temp[0] = factorial(m); // 計算 m! 的值 temp[1] = factorial(n); // 計算 n! 的值 temp[2] = factorial(m-n); // 計算 (m-n)! 的值 ans = (temp[0])/(temp[1]*temp[2]); //C(m,n)=(m!)/(n!*(m-n)!) System.out.println("C(" + m + "," + n + ")=" + ans); public static long factorial(int p) /* 函式定義 */ long result = 1L; for(int count=1;count<=p;count++) result = result * count; return result; 在這個範例中,factorial() 函式一共被呼叫了 3 次 ( 第 行 ), 充分利用函式, 提高程式碼的重複使用率 34
18 6.2.2 函式呼叫 觀念範例 6-5 : 製作一個專門用來列印九九乘法表的函式 (print99 函式 ), 該函式不接受任何傳入引數, 也不回傳任何資料 範例 6-5:ch6_05.java( 隨書光碟 myjava\ch06\ch6_05.java) /* 檔名 :ch6_05.java 功能 : 無傳入引數及回傳值的函式 */ package myjava.ch06; import java.lang.*; public class ch6_05 // 主類別 函式呼叫 public static void main(string args[]) print99(); // 函式呼叫 */ 雖然沒有引數, 但仍須寫上 () public static void print99() // 函式定義 for(int i=1;i<=9;i++) 雖然沒有參數, 但仍須寫上 () for(int j=1;j<=9;j++) System.out.print(i + "*" + j + "=" + i*j + "\t"); System.out.println(); 執行結果 :( 同範例 4-17) 範例說明 : (1) 第 13 行, 由於沒有傳入引數, 因此參數串列為空 由於函式不需要回傳值, 所以必須將函式回傳值的資料型態設為 void (2) 第 10 行為函式呼叫, 雖然不必傳入引數, 但 ( ) 仍不可省略 (3)print99() 函式中, 並無 return 敘述, 所以函式會執行到最後一行 ( 第 21 行 ), 然後才返回呼叫函式處 36
19 6.2.3 return 敘述 return 敘述一共有 2 個功用 : (1) 回傳函式資料 (2) 函式返回 其規定可歸納如下 使用 return 回傳資料的語法如下 : return 常數 變數 運算式或其他具有結果值的敘述 ; 語法說明 : (1) 回傳函式資料的資料型態必須和函式定義的回傳值資料型態相容 ( 需可進行自動轉型 ) return 敘述 範例 : int func1( ) int a; return a; double func2( ) float c=3.0f; return c; (2) 函式回傳值資料型態若被宣告為 void, 則不用 return 回傳值 (3) 若回傳值為運算式或其他具有結果值的敘述, 則會先計算其運算結果, 然後才傳回該值 38
20 6.2.3 return 敘述 使用 return 返回使用 return 返回呼叫函式敘述如下 : return; return 函式回傳值 ; 或 語法說明 : (1) 使用 return 將返回呼叫函式處, 並由呼叫函式的下一個敘述開始執行 (2) 一個函式的 return 並不限定為一個, 不過一但執行 return 敘述後, 其餘函式內未被執行的敘述將不會被執行 (3) 無回傳值的函式, 不需要用 return 敘述返回, 此時函式將被執行完畢後, 才會返回呼叫函式處 而若使用 return 敘述返回, 則在 return 之後的敘述不會被執行 觀念範例 6-6 : 設計一個包含有多個 return 敘述的函式, 觀察其執行過程 範例 6-6:ch6_06.java( 隨書光碟 myjava\ch06\ch6_06.java) return 敘述 /* 檔名 :ch6_06.java 功能 :return 返回 */ package myjava.ch06; import java.lang.*; public class ch6_06 // 主類別 public static void main(string args[]) int k; k=func1(); System.out.println("k=" + k); public static int func1() int a=5,b=7; a++; if (a>0) return a+b; a++; if (a>0) return a+b; a++; return a+b; 執行結果 k=13 40
21 6.2.3 return 敘述 範例說明 : (1) 程式執行的行數順序為 ( 函式呼叫 ) ( 返回 ) 13 (14) 亦即程式的 21~24 行將不會被執行 (2) 執行第 12 行時, 會先計算 a+b 的值 (6+7=13), 然後回傳 13 給呼叫函式的敘述, 並返回函式呼叫處, 因此 k 為 13 Coding 注意事項 Java 的編譯器頗為聰明, 如果您刪除第 20 行與第 22 行的 if(a>0), 僅留下 return a+b;, 則它會指出第 21 行執行不到, 提醒程式設計師, 程式可能有某些邏輯上的錯誤 但若如本範例, 加上一些條件判斷後, 它就不一定能夠找出程式邏輯上的錯誤 return 敘述 Coding 偷撇步 如果您將第 24 行改寫如第 20 行, 則 Java 的編譯器會顯示出找不到 return 的錯誤 ( 因為該函式的宣告處已經註明要回傳一個 int 型態的回傳值 ), 雖然這樣子的修改, 程式實際上還是會回傳一個值, 但 Java 的編譯器並沒有那麼聰明 此時, 可以在最後加入 return 0; 之類的敘述以避開編譯錯誤, 不過您必須先確定該行絕對不可能被執行到 42
22 6.3 好用的亂數函式 在現實生活中, 有許多的現象與隨機亂數有關 在程式設計中, 我們可以使用亂數函式來模擬大量的隨機資料, 例如統計與實驗 電腦遊戲 樂透開獎等等 一般來說, 我們可以自行完成大多數的函式, 但若使用他人完成且可信賴的函式將可縮減程式的開發時程例如您知道如何開發一個取亂數的函式嗎? 想不通嗎? 沒關係, 我們只要使用 java.lang.math 類別所提供的 random( ) 函式即可 好用的亂數函式 random( ) 取亂數 所屬類別 :java.lang.math 語法 :public static double random() 功能 : 回傳一個介於 0.0~1.0( 不含 1.0) 的亂數 語法說明 : 回傳值為隨機產生的一個 double 浮點數 觀念範例 6-7 : 使用 Math.random() 亂數函式產生 6 個隨機亂數 範例 6-7:ch6_07.java( 隨書光碟 myjava\ch06\ch6_07.java) 44
23 6.3 好用的亂數函式 /* 檔名 :ch6_07.java 功能 : 亂數函式 random */ package myjava.ch06; import java.lang.*; import java.lang.math; public class ch6_07 // 主類別 public static void main(string args[]) for(int i=1;i<=6;i++) System.out.println(" 第 " + i + " 個隨機亂數為 " + Math.random()); 執行結果 : random 所屬類別, 可省略 第 1 個隨機亂數為 第 2 個隨機亂數為 第 3 個隨機亂數為 第 4 個隨機亂數為 第 5 個隨機亂數為 第 6 個隨機亂數為 好用的亂數函式 範例說明 : (1) 迴圈執行 6 次, 使用 random 函式產生 6 個隨機亂數 每次重新執行本範例, 將會得到隨機的 6 個亂數 ( 通常是不同的 6 個亂數 ) (2) 由於產生的亂數是一個小數, 而應用卻常常需要整數的亂數值, 因此可以對所取得的亂數值, 進行乘法或加法, 然後透過型態轉換取得應用所需要的整數亂數值 實用範例 6-8 : 使用亂數函式產生 6 個 1~49 的整數, 並存放於整數陣列中 ( 不要求數字不重覆 ) 範例 6-8:ch6_08.java( 隨書光碟 myjava\ch06\ch6_08.java) 46
24 6.3 好用的亂數函式 /* 檔名 :ch6_08.java 功能 : 產生 6 個 1~49 的隨機亂數 */ package myjava.ch06; import java.lang.*; import java.lang.math; public class ch6_08 public static void main(string args[]) int lotto[]=new int[6]; 執行結果 第 1 個隨機亂數為 13 第 2 個隨機亂數為 27 第 3 個隨機亂數為 14 第 4 個隨機亂數為 14 第 5 個隨機亂數為 34 第 6 個隨機亂數為 35 for(int i=1;i<=6;i++) 轉換為整數資料型態 lotto[i-1]= (int)((math.random()*49)+1); System.out.println(" 第 " + i + " 個隨機亂數為 " + lotto[i-1]); 範例說明 : 由於 Math.random()*49 可產生的亂數將介於 0.0~49.0( 不含 49.0), 故將之加 1 後為 1.0~50.0( 不含 50.0), 強制型態轉換為 int 整數類型, 則小數部分會被去除, 就可以得到 1~49 的亂數 ( 在後面的範例中, 我們將修改為 6 個數字不得重複, 並加上一個特別號, 符合真正的樂透開獎 ) 引數串列與引數傳遞 使用函式時, 呼叫的一方可以取得一個回傳值, 但是當需要回傳超過一個回傳值的時候, 該怎麼辦呢? 基本上, 大多數的程式語言都是靠 傳址呼叫, 藉由共用同一塊記憶體來達到目的 同樣的問題若遇到物件導向程式語言時, 解法就更多了 基本上, 物件導向程式語言有兩個方法可以解決這個問題第一種方法是使用 欄位 ( 例如將資料宣告為類別的欄位, 則類別內的所有函式都可以取用 ), 但是這個方法並非適用於所有場合, 因為除了呼叫方與被呼叫方可以使用這些欄位外, 類別內的其他函式也可以使用這些欄位 另一種方法則是靠 傳址呼叫, 藉由共用同一塊記憶體來達到目的 48
25 6.4 引數串列與引數傳遞 在 Java 中 呼叫端與被呼叫端的串列分別稱為 引數串列 與 參數串列, 如下圖中的 a,b 為引數,x,y 為參數 圖 6-7 引數與參數 引數串列與引數傳遞 關於引數與參數的資料傳遞, 一般程式語言會將之分為傳值呼叫 (Call by value) 與傳址呼叫 (Call by address) 兩種, 其個別意義如下 : 傳值呼叫 : 效果 : 接收端 ( 被呼叫端 ) 如何改變參數值, 都不會影響傳遞端 ( 呼叫端 ) 的引數值 作法 : 只將引數的值傳遞給參數, 亦即在被呼叫端建立一個複本來接收此值, 因此引數與參數使用不同的記憶體空間, 故而各自獨立, 不互相影響 傳址呼叫 : 效果 : 接收端 ( 被呼叫端 ) 若改變參數值, 則傳遞端 ( 呼叫端 ) 的引數值也會跟著改變 作法 : 將引數的位址傳遞給參數, 使得引數與參數使用了相同的記憶體空間來存放內容, 故而參數值一改變 ( 該記憶體內容被改變 ), 引數內容就會跟著改變, 彼此互相影響 50
26 6.4 引數串列與引數傳遞 當被呼叫端有一個以上的資料想要和呼叫端溝通時, 程式語言必須提供 傳址呼叫功能 或 類似傳址呼叫效果 的機制, 否則, 該程式語言就無法達到此需求, 也會因此無法被大眾所接受 故而, 所有的高階程式語言都提供了類似的機制 有些高階語言直接提供了傳址呼叫功能直接提供傳址呼叫 (Call by address) 功能的程式語言 ( 例如 C++ ), 大多把傳址呼叫以傳參考呼叫 (Pass by reference) 來實現 有些高階語言則只提供了類似的功能 而傳值呼叫由於可以避免邊際效應 ( 亦即呼叫者與被呼叫者並不相互影響 ) 因此, 所有的高階程式語言都直接提供了此一機制有些 ( 例如 VB.NET) 還被設定為預設機制 引數串列與引數傳遞 對於上述兩種傳遞引數的機制,Java 僅支援其中的傳值呼叫 (Call by Value), 在 Java 中將之稱為傳值呼叫 (Pass by value) 但為了共用同一塊記憶體, 因此 Java 對於傳址呼叫, 則是利用傳 參考值 來達成類似的效果 當然也有些人或某些書籍將 Java 傳遞物件或陣列時, 視為傳參考呼叫 (Pass by reference), 但這是不正確的說法 Java 傳遞物件或陣列時, 嚴謹的說法應該是傳參考值呼叫 (Pass by value of reference) 52
27 6.4 引數串列與引數傳遞 筆者的話 每年在程式設計討論區都會引起爭議的兩個問題是 (1)Java 是否支援傳參考呼叫 (Pass by reference)?(2)java 到底有沒有像 C 語言的指標? 關於 Java 究竟有沒有傳參考呼叫 (Pass by reference) 機制? 嚴格來說,Java 確實只有傳值呼叫 (Pass by value), 只不過這個值在引數為原始資料型態時, 是一個數值 字元或布林值, 而當引數為陣列或物件時, 它將會是一個參考 (reference), 這是因為陣列名稱與物件名稱原本就只是個參考, 而非實體 少數書籍對這個問題有明確的說明, 以 O'Reilly's Java in a Nutshell by David Flanagan 一書為例, 它的原文解釋如下 :( 我們將於介紹物件時, 透過一個範例研究這個問題 ) "Java manipulates objects 'by reference', but it passes object references to methods 'by value'." As a result, you cannot write a standard swap method to swap objects 引數串列與引數傳遞 筆者的話 關於 Java 到底有沒有像 C 語言的指標? 答案是有的,Java 的參考就是 C 語言的指標 ; 不過它和 C 語言不同之處在於,Java 不可以對參考進行加減法任意移動所指向的記憶體位址, 但可以將它指向另一個合法物件實體的記憶體位址 事實上, 這個問題與前一個問題有高度相關,Java 的傳參考值呼叫 (Pass by value of reference) 事實上就是 C 語言的傳指標呼叫 (Pass by pointer)! 您或許會問,C 語言的傳指標呼叫不就是傳址呼叫 (Call by address) 嗎? 那 Java 不也支援了傳址呼叫 (Call by address) 了? 事實上不是這樣的 其實, 不論是 C 語言的傳指標呼叫或 Java 的傳參考值呼叫都屬於傳值呼叫 (Call by value), 會有這樣的誤解, 代表您可能對於 C 語言的傳指標呼叫有錯誤的認知 有興趣的讀者, 可以參閱筆者所著之 C 語言初學指引第四版的說明 由於本書非講解 C 語言的書籍, 因此, 在此僅提示 C 語言傳遞陣列是傳遞一個指標常數, 能夠將引數指定為常數, 必定不是傳址呼叫 (Call by address), 因為傳址呼叫的被呼叫方參數, 可以影響呼叫方的引數, 而常數是不允許被改變的, 故而只要是傳遞常數類的引數, 必定使用的是傳值呼叫 (Call by value) 54
28 6.4.1 傳值呼叫 (Pass by value) 什麼是 Java 的傳值呼叫 (Pass by value) 呢? 傳值呼叫就是在呼叫函式時, 只會將引數 數值 傳遞給函式中相對應的參數, 作為函式啟動時的初始值換句話說, 參數實際上會產生一個引數的複本, 如此一來呼叫方的引數與被呼叫方的參數將佔用不同的記憶體空間所以不論被呼叫函式在執行過程中如何改變參數的變數值, 都不會影響原本呼叫方引數的變數值, 這種引數傳遞方式稱為 傳值呼叫 傳值呼叫 (Pass by value) 在 Java 中, 如果傳遞的引數是原始資料型態的變數 ( 例如 int, float, char, boolean) 則採用傳值呼叫傳送, 亦即只把 值 傳送過去, 並沒有把記憶體位址也傳送過去 我們藉由下面一個範例重新闡述何謂傳值呼叫 (Pass by value) 觀念範例 6-9 : 透過觀察變數內容, 了解傳值呼叫的引數傳遞原理 範例 6-9:ch6_09.java( 隨書光碟 myjava\ch06\ch6_09.java) 56
29 6.4.1 傳值呼叫 (Pass by value) /* 檔名 :ch6_09.java 功能 : 傳值呼叫 */ package myjava.ch06; import java.lang.*; public class ch6_09 public static void main(string args[]) int m=1,n=1; func1(m,n); System.out.println("main( ) 的 m=" + m); System.out.println("main( ) 的 n=" + n); public static void func1(int a,int b) a=a+10; b=b+100; System.out.println("func1() 的 a=" + a); System.out.println("func1() 的 b=" + b); 執行結果 func1() 的 a=11 func1() 的 b=101 main( ) 的 m=1 main( ) 的 n= 傳值呼叫 (Pass by value) 範例說明 : (1) 當第 12 行呼叫 func1 函式後, 不論 func1 函式如何運算, 影響到的變數只有 a,b, 而不會影響呼叫它的 m,n 變數, 因為兩者的記憶體位置不同 (2) 本範例的引數傳遞如下 :( 引數傳遞完畢後, 參數與引數就相互不干擾 ) 圖 6-8 傳值呼叫示意圖 58
30 6.4.1 傳值呼叫 (Pass by value) 小試身手 6 1 (3) 本範例即使將 main() 函式的變數 m,n 也命名為 a,b, 仍舊不會影響引數傳遞的過程與結果, 因為它們只是各函式的區域變數, 因此仍將佔用不同的記憶體位置 (4) 由於 a,b 是 func1 的區域變數, 故當函式返回後, 上圖中 a,b 所佔用的記憶體將被釋放 請將範例 6 9 的第 10 行改為 final int m=1,n=1;, 然後重新編譯與執行, 證明傳值呼叫可將引數設定為不可變動之變數 小試身手 6 2 請在範例 6 9 的第 12~13 行間, 加入 func1(2,4); 敘述, 然後重新編譯與執行, 證明傳值呼叫可將引數設定為常數 傳遞陣列 傳遞陣列首先要將參數的資料型態設定為陣列, 並且維度必須正確例如傳遞一維整數陣列應該宣告為 int[], 二維陣列應該宣告為 int[][], 依此類推 當傳遞的引數被宣告物件或陣列時由於物件名稱與陣列名稱本身只是一個實體的參考 (reference), 故它只會將該參考的值傳遞給被呼叫端相對應的參數 故被呼叫端函式可以透過這個參考修改原呼叫端的物件或陣列實體內容 有些書籍將這種引數傳遞視為傳參考呼叫 (pass by reference), 但其實這並不精確本書將傳遞陣列或物件視為傳 參考值 呼叫 (pass by value of reference) 60
31 6.4.2 傳遞陣列 我們透過下面這個範例, 觀察傳遞陣列時的引數傳遞原理 觀念範例 6-10 : 利用傳 參考值 呼叫傳遞陣列 範例 6-10:ch6_10.java( 隨書光碟 myjava\ch06\ch6_10.java) /* 檔名 :ch6_10.java 功能 : 傳參考值呼叫 ( 傳遞陣列 ) */ package myjava.ch06; import java.lang.*; public class ch6_10 // 主類別 public static void main(string args[]) int lotto[]=new int[6]; 傳遞陣列 執行結果 : generate_lotto(lotto); System.out.println(" 樂透號碼如下..."); for(int i=0;i<6;i++) System.out.print(lotto[i] + "\t"); public static void generate_lotto(int[] arr) for(int i=0;i<arr.length;i++) arr[i]= (int)((math.random()*49)+1); System.out.println(" 第 " + (i+1) + " 個隨機亂數為 " + arr[i]); 第 1 個隨機亂數為 31 第 2 個隨機亂數為 15 第 3 個隨機亂數為 21 第 4 個隨機亂數為 32 第 5 個隨機亂數為 39 第 6 個隨機亂數為 16 樂透號碼如下
32 6.4.2 傳遞陣列 範例說明 : 小試身手 6 3 (1) 從執行結果中, 我們可以得知 lotto 陣列與 arr 陣列都參考到同一個陣列實體, 所以在 generate_lotto 函式中對 arr 陣列元素的修改都將會影響 main 函式的 lotto 陣列元素值 ( 共用同一塊記憶體空間 ) (2) 第 18 行的參數也可以修改為 int arr[], 只要是正確的陣列變數宣告方式即可 (3) 事實上, 當呼叫 generate_lotto 函式, 記憶體的變化如下 : 請在範例 6 10 第 10 行改為 final int lotto[]=new int[6];, 然後重新編譯與執行, 證明傳遞陣列時, 雖然是傳遞參考並且改變了陣列內容, 但陣列參考並不會被改變, 因為我們已經宣告為 final 陣列變數, 因此 lotto 不會再參考到其他的陣列實體 傳遞陣列 圖 6-9 傳遞陣列示意圖 ( 傳參考值呼叫 ) 64
33 6.5 回傳陣列 既然陣列或物件變數是一個參考, 當我們要回傳陣列或物件時, 是否需要回傳整個陣列或物件實體, 還是只要回傳變數 ( 參考 ) 即可 我們透過下面這個範例來說明 : 觀念範例 6-11 : 改寫範例 6-10, 將產生陣列實體敘述放置於被呼叫函式內, 並回傳該陣列 範例 6-11:ch6_11.java( 隨書光碟 myjava\ch06\ch6_11.java) /* 檔名 :ch6_11.java 功能 : 回傳陣列 */ package myjava.ch06; import java.lang.*; 回傳陣列 public class ch6_11 // 主類別 public static void main(string args[]) int lotto[]; lotto=generate_lotto(); System.out.println(" 樂透號碼如下..."); for(int i=0;i<lotto.length;i++) System.out.print(lotto[i] + "\t"); public static int[] generate_lotto() int arr[]=new int[6]; for(int i=0;i<arr.length;i++) arr[i]= (int)((math.random()*49)+1); System.out.println(" 第 " + (i+1) + " 個隨機亂數為 " + arr[i]); return arr; 66
34 6.5 回傳陣列 執行結果 :( 同範例 6-10, 但因亂數緣故, 值可能不同 ) 範例說明 : (1) 第 18 行的回傳值資料型態為 int[], 代表要回傳一個整數一維陣列 (2) 從執行結果中, 我們可以得知 lotto 陣列變數可以存放 arr 所回傳的陣列參考, 使得將之指向同一個陣列實體, 然而, 我們在前面提過, 在函式內宣告的為區域變數, 而 arr 也是一個區域變數, 這意味著當函式執行完畢時, 它將被釋放 但釋放的只是陣列的參考而非陣列實體, 因此在函式內產生的陣列實體仍可以保留, 並由第 15 行取出其元素 回傳陣列 (3) 您或許會產生一個疑問, 萬一該函式在宣告時並不回傳陣列變數, 那麼當函式執行完畢時, 陣列參考被釋放了, 而陣列實體並未被釋放, 可是又沒有任何參考變數可以指向它, 那麼陣列實體豈不成為記憶體中的垃圾而浪費記憶體空間嗎? 沒錯, 但您不用煩惱, 因為 Java 提供記憶體垃圾收集 (Garbage Collection) 機制, 對於沒有被任何變數參考的陣列或物件實體,JVM 將會定期地自動清除 我們將於後面章節說明 Java 的 Garbage Collection 機制 (4) 本範例的記憶體變化如下 : 68
35 6.5 回傳陣列 圖 6-10 回傳陣列示意圖 搜尋演算法 補充 排序的主要目的通常是方便於搜尋資料 ( 即使是僅將結果顯示於螢幕或列印出來, 也是為了提供使用者快速尋找資料 ), 至於搜尋的方法, 其實也是分成許多種, 每一種的難度與效率皆不相同, 以下是兩種常用的搜尋法 : 1. 循序搜尋法 2. 二分搜尋法 70
36 6.6 搜尋演算法 補充 循序搜尋法 循序搜尋 是一種簡單到不能再簡單的搜尋方法, 也就是從第一筆資料開始尋找, 然後是第二筆資料 一直到找到所要的資料或全部資料被找完為止 因此, 假設有 N 筆資料, 則最差需要作 N 次比較, 而平均則需要 N/2 次比較 通常, 我們會在資料量比較少或資料未經排序的狀況下使用 循序搜尋法 實用範例 6-12 : 使用循序搜尋法在未排序的資料中, 尋找所需要的資料 57 範例 6-12:ch6_12.java( 隨書光碟 myjava\ch06\ch6_12.java) 搜尋演算法 補充 /* 檔名 :ch6_12.java 功能 : 循序搜尋法 */ package myjava.ch06; import java.lang.*; import java.io.console; public class ch6_12 public static void main(string args[]) int workarr[]=43,23,67,27,39,15,39,37,57,26,14; int findnum,location; Console console=system.console(); 執行結果 System.out.print(" 請輸入您要找的數值 :"); findnum=integer.parseint(console.readline()); location=seqsearch(findnum,workarr); if(location==-1) System.out.println(" 在陣列中找不到要找的數值 "); else System.out.println(" 數值 " + findnum + " 位於 work[" + location + "]"); 請輸入您要找的數值 :57 數值 57 位於 work[8] 72
37 6.6 搜尋演算法 補充 public static int seqsearch(int target,int[] arr) for(int i=0;i<arr.length;i++) if(target == arr[i]) return i; return -1; // 找到了 // 完全找不到 範例說明 : (1) 第 24~30 行是循序搜尋函式 可以接受一個尋找目標 ( 整數 int 資料型態 ) 及一個工作陣列 語法如下 : 所屬類別 : 主類別語法 :public static int seqsearch(int target,int[] arr) 功能 : 循序搜尋 引數 :target 為尋找目標 arr[ ] 為工作陣列 回傳值 : 若 target 位於 arr[ ] 陣列中, 則回傳索引值 若不位於 arr[ ] 陣列中, 則回傳 -1 (2) 第 17 行使用 傳值呼叫 傳遞 findnum target 參數 使用 傳參考值呼叫, 傳送 workarr arr 陣列變數 搜尋演算法 補充 二分搜尋法 二分搜尋法比循序搜尋法來得有效率許多, 平均只需要做 log 2 N+1 次比較即可找到資料 雖然速度比較快, 但使用二分搜尋法找尋資料必須先將資料經過排序之後, 才可以使用二分搜尋法 以下是二分搜尋法的原理及步驟 : 圖 6-11 二分搜尋法 74
38 6.6 搜尋演算法 補充 二分搜尋法原理 先從記錄中央開始搜尋, 若該記錄比目標還小, 則往大的剩餘另一半搜尋若記錄比目標還大, 則往小的剩餘另一半搜尋 ; 相等, 則代表找到資料 重覆此步驟直到找到資料為止, 或者發現要搜尋的資料不存在 因此, 每次會剩下 1/2 1/4 1/8, 在第 k 次比較時, 最多只剩下 n/2 k 筆記錄未搜尋, 在最壞的狀況下, 只剩單一記錄 n/2 k =1, 也就是 k=log 2 n, 所以最多的比較次數為 log 2 n 搜尋演算法 補充 演算法 ( 使用非正式但較接近 Java 語法的虛擬碼 ): 輸入 : 已排序的資料 X[0]~X[n-1] 要找尋的目標資料 k 輸出 : 目標資料的索引值 middle left 0 right n-1 while (left right) do middle (left+right) div 2 // 除 2 取商 case k > x[middle]: left middle+1 // 放棄左半部 k = x[middle]: return middle k < x[middle]: right middle-1 // 放棄右半部 endcase endwhile return -1 // 沒有符合的記錄 76
39 6.6 搜尋演算法 補充 實例說明 : 8 個陣列元素 A[0]~A[7] 為 33,41,52,54,63,74,79,86, 尋找目標為 52, 使用二分搜尋法搜尋, 則以下是詳細步驟 : 1. 計算中間位置為 (0+7)/2=3.5 取整數為 3 2. A[3]=54>52, 所以 right=3-1=2 3. 計算中間位置為 (0+2)/2=1 4. A[1]=41<52, 所以 left=1+1=2 5. 計算中間位置為 (2+2)/2=2 6. A[2]=52, 所以找到了 不實用範例 6-13 : 使用二分搜尋法在已排序的資料中, 尋找所需要的資料 52 範例 6-13:ch6_13.java( 隨書光碟 myjava\ch06\ch6_13.java) 搜尋演算法 補充 /* 檔名 :ch6_13.java 功能 : 二分搜尋法 */ package myjava.ch06; import java.lang.*; import java.io.console; public class ch6_13 public static void main(string args[]) int workarr[]=33,41,52,54,63,74,79,86; int findnum,location; Console console=system.console(); 執行結果 System.out.print(" 請輸入您要找的數值 :"); findnum=integer.parseint(console.readline()); location=binarysearch(workarr,findnum); if(location==-1) System.out.println(" 在陣列中找不到要找的數值 "); else System.out.println(" 數值 " + findnum + " 位於 work[" + location + "]"); 請輸入您要找的數值 :52 數值 52 位於 work[2] 78
40 6.6 搜尋演算法 補充 public static int binarysearch(int[] x,int k) int left,right,middle; left=0; right=x.length-1; while(left<=right) middle=(left+right)/2; if(k==x[middle]) return middle; if(k>x[middle]) left=middle+1; // 放棄左半部 else right=middle-1; // 放棄右半部 return -1; 範例說明 : (1) 第 24~38 行是二分搜尋函式 可以接受一個尋找目標 ( 整數 ) 及一個已排序的工作陣列 語法如下 : 所屬類別 : 主類別語法 :public static int binarysearch(int[] x,int k) 功能 : 二分搜尋 引數 :k 為尋找目標 x[ ] 為已排序的工作陣列 回傳值 : 若 k 位於 x 陣列中, 則回傳索引值 若不位於 x 陣列中, 則回傳 搜尋演算法 補充 (2) 第 17 行使用 傳值呼叫 傳遞 findnum k 參數 使用 傳參考值呼叫, 傳送已排序的陣列 workarr x 陣列變數 (3)workArr 陣列一定要先經過排序完成, 否則無法使用二分搜尋法完成工作 事實上, 二分搜尋法如同排序, 已經被 Java 納入 Arrays 類別的方法, 名稱為 binarysearch 故上一個範例, 我們將之歸類為不實用範例 想要使用二分搜尋法並不需要自行撰寫程式, 並且 Java 提供的二分搜尋法, 還可以針對各種資料型態進行搜尋, 甚至還可以指定要搜尋的陣列範圍 以下, 我們僅提供整數陣列的二分搜尋法之語法, 其餘請自行參閱 Java 說明文件 80
41 6.6 搜尋演算法 補充 所屬類別 :java.util.arrays 語法 :public static int binarysearch(int[] a,int key) 功能 : 二分搜尋 引數 :key 為尋找目標 a[ ] 為已排序的工作陣列 回傳值 : 若 key 位於 a 陣列中, 則回傳索引值 若不位於 a 陣列中, 則回傳負值 實用範例 6-14 : 改寫範例 , 使用 Arrays 類別的 sort 與 binarysearch 對未排序的陣列進行搜尋, 判斷資料 57 是否位於陣列中 範例 6-14:ch6_14.java( 隨書光碟 myjava\ch06\ch6_14.java) 搜尋演算法 補充 /* 檔名 :ch6_14.java 功能 :sort 與 binarysearch 方法 */ 實用範例 6-14 : 改寫範例 , 使用 package myjava.ch06; 執行結果 import java.lang.*; Arrays 類別的 sort 與 binarysearch 對未排序的陣 import java.io.console; 請輸入您要找的數值 :57 import java.util.arrays; 數值存在於陣列中列進行搜尋, 判斷資料 sort 與 binarysearch 57 是否位於陣列中 隸屬於該類別範例 6-14:ch6_14.java( 隨書光碟 public class ch6_14 myjava\ch06\ch6_14.java) public static void main(string args[]) int workarr[]=43,23,67,27,39,15,39,37,57,26,14; int findnum,location; Console console=system.console(); 對陣列排序 Arrays.sort(workArr); System.out.print(" 請輸入您要找的數值 :"); findnum=integer.parseint(console.readline()); location=arrays.binarysearch(workarr,findnum); if(location<0) System.out.println(" 在陣列中找不到要找的數值 "); else System.out.println(" 數值存在於陣列中 "); 對陣列進行二分搜尋 82
42 6.6 搜尋演算法 補充 範例說明 : 由於二分搜尋只能針對已排序的目標陣列進行搜尋, 故在第 18 行先使用 sort 進行排序, 然後在第 21 行進行二分搜尋 如果您想要印出 57 所在的索引, 光是印出 location 是無法達成的, 因為在呼叫 sort 時, 陣列已經被排序過, 由於傳遞陣列必定是傳參考值呼叫, 故陣列實體內容已經被改變, 所以第 18 行之後的 57 已經不位於原本在陣列中的位置 實用範例 6-15 : 使用亂數函式 搜尋函式, 完成樂透開獎遊戲 ( 產生 6 個 1~49 的整數號碼並存放於整數陣列以及 1 個特別號, 且這 7 個號碼不得重覆 ) 範例 6-15:ch6_15.java( 隨書光碟 myjava\ch06\ch6_15.java) 搜尋演算法 補充 /* 檔名 :ch6_15.java 功能 : 設計樂透開獎遊戲 */ package myjava.ch06; import java.lang.*; public class ch6_15 // 主類別 public static void main(string args[]) int special; // 存放特別號 int lotto[]=new int[6]; // 存放六球 special=generate_lotto(lotto); System.out.println(" 樂透號碼如下..."); for(int i=0;i<lotto.length;i++) System.out.print(lotto[i] + "\t"); System.out.println(); System.out.println(" 特別號 :" + special); public static int generate_lotto(int[] arr) int generatenum; 84
43 6.6 搜尋演算法 補充 for(int i=0;i<arr.length;i++) generatenum=(int)((math.random()*49)+1); while (seqsearch(generatenum,arr)!=-1) generatenum=(int)((math.random()*49)+1); arr[i]=generatenum; generatenum=(int)((math.random()*49)+1); while (seqsearch(generatenum,arr)!=-1) generatenum=(int)((math.random()*49)+1); return generatenum; public static int seqsearch(int target,int[] arr) for(int i=0;i<arr.length;i++) if(target == arr[i]) return i; return -1; // 找到了 // 完全找不到 是否與陣列元素重複 特別號是否與其他號碼重複 搜尋演算法 補充 執行結果 : 樂透號碼如下 特別號 :35 範例說明 : (1) 這個程式使用了前面範例介紹的兩個函式, 分別是 [1] 亂數產生 1~49 的數字 [2] 使用循序搜尋決定開出的號碼是否重複 (2) 我們修改了 generate_lotto() 函式, 使得它能夠回傳一個整數值, 以代表特別號 (3) 由於陣列自動初始化會將整數陣列元素設定為 0, 而呼叫循序搜尋時, 由於輸入的球號必定為 1~49( 不會為 0), 故仍可適用 (4) 本範例的兩個函式可用於不限定樂透開獎球數的遊戲中, 例如可以用來製作大樂透 (49 選 7 球 ) 國外的超級樂透 (49 選 8 球, 只要在陣列宣告時多宣告 1 個元素即可 ) 86
44 6.6 搜尋演算法 補充 (5) 函式呼叫關係如下圖 ( 本範例未將 6 個樂透開獎號碼排序顯示 ) main 函式的參數串列 函式的參數串列可以接受呼叫者傳入的引數值, 那麼 main 函式也可以嗎? 答案是肯定的, 不過 main 的參數串列已經在 Java 中詳細定義, 使用者不得更改 main 函式的參數是用來接收 JVM 的命令引數 例如 : 我們在 Dos 命令列中, 若輸入 java test This is a book, 則代表要求 JVM 執行 test 類別, 並將 This is a book 等四個字串傳入 test 類別的 main 函式中 88
45 6.7 main 函式的參數串列 main 函式的參數被宣告為字串陣列 String[] args 或 String args[] 我們可以在 main() 函式中取用這些字串, 做其他進一步的應用 觀念範例 6-16 : 接收由 JVM 傳送過來的命令列引數 範例 6-16:ch6_16.java( 隨書光碟 myjava\ch06\ch6_16.java) main 函式的參數串列 /* 檔名 :ch6_16.java 功能 :main 函式的參數 */ package myjava.ch06; import java.lang.*; public class ch6_16 // 主類別 public static void main(string args[]) System.out.println(" 本程式共接受到 " + args.length + " 個輸入引數 "); for(int i=0;i<args.length;i++) System.out.println("args[" + i + "] 字串為 " + args[i]); 執行結果 : C:\>java myjava.ch06.ch6_16 This is a book 本程式共接受到 4 個輸入引數 args[0] 字串為 This args[1] 字串為 is args[2] 字串為 a args[3] 字串為 book 90
46 6.7 main 函式的參數串列 範例說明 : 在執行結果中, 我們先要求 JVM 執行 myjava.ch06 Package 的 ch6_16 類別, 並傳送 This is a book 等四個額外引數給 ch6_16 類別的 main() 函式 實用及觀念範例 6-17 : 由於範例 6-15 可以修改為 其他球數的樂透遊戲, 因此我們將範例 6-17 改寫為由使用者在輸入命令列引數時決定要開出的球數 ( 球數當然不應該超過 48 球, 因為必須保留一個球作為特別號 ) 範例 6-17:ch6_17.java( 隨書光碟 myjava\ch06\ch6_17.java) main 函式的參數串列 /* 檔名 :ch6_17.java 功能 : 設計樂透開獎遊戲 */ package myjava.ch06; import java.lang.*; public class ch6_17 // 主類別 public static void main(string args[]) int special,balls=6; // 存放特別號 if(args.length>0) balls=integer.parseint(args[0]); if((balls>48) (balls<0)) return; int lotto[]=new int[balls]; special=generate_lotto(lotto); System.out.println(" 樂透號碼如下..."); for(int i=0;i<balls;i++) if((i%6==0)&&(i!=0)) System.out.println(); System.out.print(lotto[i] + "\t"); System.out.println(); System.out.println(" 特別號 :" + special); // 球數錯誤, 離開 // 存放 balls 球 92
47 6.7 main 函式的參數串列 : : public static int generate_lotto(int[] arr) 同範例 6-15 的第 23~39 行之 generate_lotto 函式內容 public static int seqsearch(int target,int[] arr) 同範例 6-15 的第 44~47 行之 seqsearch 函式內容 執行結果 : C:\>java myjava.ch06.ch6_17 48 樂透號碼如下 特別號 : main 函式的參數串列 範例說明 : (1) 我們修改了 main() 函式, 讓使用者可以指定開出的球數 ( 若使用者輸入超過 48 或其他文字, 則會執行 return 提前結束程式 ) (2) 第 13 行, 由於輸入的引數會被存放到字串陣列, 因此, 必須將字串轉換為數值 94
48 6.8 函式的 final 參數 在前面曾經提及, 若區域變數被宣告為 final, 則該區域變數在第一次被設定某個值之後, 就不可以再被設定 由於函式參數列的參數可以被當作區域變數使用, 因此, 也可以被宣告為 final, 而宣告為 final 的參數, 在函式內完全不能被重新設定 這是因為當函式呼叫發生而傳遞引數時, 參數就被設定了某個初值 函式的 final 參數 通常將參數宣告為 final, 是為了避免函式不小心修改了該參數, 因此你可以把該參數視為 特殊的 常數來使用 如果您只是為了避免呼叫端的引數被修改, 則使用 final 來宣告是不必要或無意義的, 請見下列的分析 Case1: 呼叫端的引數為原始資料型態變數, 此時, 由於是傳值呼叫, 因此被呼叫的函式並不會改變原呼叫端的引數內容 所以不需要宣告為 final 96
49 6.8 函式的 final 參數 Case2: 呼叫端的引數為常數 ( 例如 3,5.7,'r',"abc"), 此時, 由於是呼叫端為常數, 所以不可能被更改 所以不需要宣告為 final Case3: 呼叫端的引數為陣列變數或物件變數 ( 參考 ), 由於採用傳參考值呼叫, 因此, 即使您使用了 final 來宣告參數, 代表的只不過是陣列或物件變數不會被改變, 而非所指實體不會被改變, 所以想要藉此達成陣列實體內容或物件實體內容不會被改變是行不通的 請見下一個範例 觀念範例 6-18 : 釐清函式呼叫的引數傳遞與 final 參數的效果 範例 6-18:ch6_18.java( 隨書光碟 myjava\ch06\ch6_18.java) 函式的 final 參數 /* 檔名 :ch6_18.java 功能 :final 陣列參數 */ package myjava.ch06; import java.lang.*; public class ch6_18 public static void main(string args[]) int orgarr[]=new int[3]; for(int i=0;i<orgarr.length;i++) orgarr[i]=i; func1(orgarr); for(int i=0;i<orgarr.length;i++) 執行結果 orgarr[0]=0 orgarr[1]=1 orgarr[2]=4 System.out.println("orgArr[" + i + "]=" + orgarr[i]); public static void func1(final int[] arr1) int arr2[]=5,10,15; 修改陣列實體的內容 for(int i=0;i<arr1.length;i++) arr1[i]=arr1[i]*arr1[i]; //arr1=arr2; 不合法的敘述 98
50 6.8 函式的 final 參數 範例說明 : (1) 第 11~12 行, 已經將 orgarr 的陣列實體內容設定為 0,1,2 (2) 第 13 行呼叫 func1, 並將 orgarr 的陣列參考傳遞給 arr1 因此 arr1 被第一次設定 (3) 由於 arr1 被宣告為 final 且設定過一次, 因此第 23 行欲將 arr1 改為參考 arr2 的陣列實體時, 代表修改 arr1 陣列參考, 將會出現編譯錯誤, 因為 arr1 被宣告為 final, 不可再被設定一次 (4) 在第 21~22 行, 修改了 arr1 的陣列實體內容, 由於並非修改陣列參考, 因此是合法的敘述 同時, 由於陣列實體內容被改變了, 因此當函式返回時,orgArr 的陣列實體內容也是被修改過的內容, 即 0,1,4 所以我們不能透過 final 來保證原陣列內容不被更動 遞迴函式 在前面的章節中, 我們已經練習很多在函式中呼叫另一個函式的方法 聰明的讀者不知是否曾經想過, 當一個函式呼叫自己的時候會發生什麼狀況呢? 這就是所謂函式的遞迴呼叫 (recursive call) 其實 遞迴呼叫 應該明確定義如下 : 遞迴呼叫 : 一個函式經由直接或間接呼叫函式本身, 稱之為函式的 遞迴呼叫 例如 :func1() 呼叫 func1() 為直接遞迴呼叫 func1() 呼叫 func2() 且 func2() 呼叫 func1() 為間接遞迴呼叫 100
51 6.9 遞迴函式 Java 允許函式的遞迴呼叫, 通常遞迴函式可以輕鬆解決一些資訊領域常見的問題 ( 例如 : 樹狀圖的相關演算法 ), 而且相當簡潔使人易懂, 但執行效率則略遜一疇 通常初次介紹遞迴函式時, 大多以著名的費本納西數列 ( 簡稱費氏數列 ) 或河內塔等問題來解釋及示範遞迴函式, 在此我們就先來解釋何謂 費氏數列 : 遞迴函式 費氏數列 : 一個無限數列, 該數列上的任一元素值皆為前兩項元素值的和, 數列如下所示 : 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144 當我們使用數學函數來表示費氏數列時, 費氏數列的定義本身就是一個遞迴定義如下 : 費氏數列的遞迴定義式 F(0) = 0 n = 0 F(1) = 1 n = 1 F(n) = F(n 1)+F(n 2) n 2 102
52 6.9 遞迴函式 從上述定義中, 我們可以發現, 在實際計算時 例如計算 F(10), 數學的遞迴函數必須不斷地重複呼叫自己, 直到遇上非遞迴定義式為止, 才能夠求出答案 同樣地, 當我們使用 Java 設計遞迴函式時, 也必須對該函式做出某些限制條件, 以避免函式無窮的執行下去, 通常一個遞迴函式需符合下列兩個限制條件 : 遞迴函式 (1) 遞迴函式必須有邊界條件, 當函式符合邊界條件時, 就應該返回 ( 可使用 return 強制返回 ) 函式呼叫處, 在費氏數列中,F(0)=0 與 F(1)=1 就是函式的邊界條件 (2) 遞迴函式在邏輯上, 必須使得函式漸漸往邊界條件移動, 否則該函式將無法停止呼叫, 而無窮地執行下去, 由於每次的函式呼叫都會使用一些記憶體堆疊, 最終將造成記憶體不足的問題 相信讀者現在已經對於 遞迴 有了初步的概念, 現在我們直接使用遞迴函式來求解 費氏數列 的問題, 請看以下範例 104
53 6.9 遞迴函式 實用及觀念範例 6-19 : 使用遞迴, 求出費氏數列第 0~25 項的元素值 範例 6-19:ch6_19.java( 隨書光碟 myjava\ch06\ch6_19.java) /* 檔名 :ch6_19.java 功能 : 遞迴函式求費氏數列 */ package myjava.ch06; import java.lang.*; public class ch6_19 // 主類別 public static void main(string args[]) System.out.print(" 費氏數列如下 :"); for(int i=0;i<=25;i++) if(i%8==0) System.out.println(); System.out.print(Fib(i) + "\t"); System.out.println("..."); 遞迴函式 public static int Fib(int n) if((n==1) (n==0)) return n; else return Fib(n-1)+Fib(n-2); 執行結果 : 費氏數列如下 :
54 6.9 遞迴函式 範例說明 : (1) 在 main 函式中, 大多數的程式碼都是為了處理列印的問題, 實際上最重要的程式出現在第 15 行的呼叫 Fib(i), 以便計算費氏數列的元素值 (2) 您是否驚訝於 Fib() 函式竟然如此簡潔有力, 幾乎只是將數學定義式轉換為 Java 程式語法而已 事實的確如此, 這就是遞迴函式的優點 舉例來說, 當 main() 的函式呼叫敘述 Fib(4) 執行時, 函式呼叫與返回狀況如下圖 : 遞迴函式 圖 6-12 Fib(4) 的遞迴呼叫與返回 108
55 6.9 遞迴函式 從上面的範例中, 我們可以發現, 執行遞迴函式時, 可能會呼叫函式很多次, 而每一次呼叫都必須將相關資料疊入 (push) 堆疊中, 因此, 當呼叫的層次越多時, 就必須使用到非常大的堆疊記憶體空間, 同時也會耗費不少時間來處理程式的呼叫與返回, 如此一來將會使得程式非常沒有效率 因此程式設計師有時會將遞迴函式轉換成普通的迴圈結構, 節省記憶體空間並提高執行效率 舉例來說, 我們可以將上面的遞迴範例改寫為下面範例的迴圈結構 : 遞迴函式 觀念範例 6-20 : 使用迴圈, 求出費氏數列第 0~25 項的元素值 範例 6-20:ch6_20.java( 隨書光碟 myjava\ch06\ch6_20.java ) /* 檔名 :ch6_20.java 功能 : 使用迴圈求費氏數列 */ package myjava.ch06; import java.lang.*; public class ch6_20 // 主類別 public static void main(string args[]) System.out.print(" 費氏數列如下 :"); for(int i=0;i<=25;i++) if(i%8==0) System.out.println(); System.out.print(Fib(i) + "\t"); System.out.println("..."); 110
56 6.9 遞迴函式 public static int Fib(int n) int n1=0,n2=0,sum=1; if((n==1) (n==0)) return n; else for(int i=2;i<=n;i++) n1=sum; sum=sum+n2; n2=n1; return sum; 執行結果 :( 同範例 6-19) 範例說明 : 明顯地, 使用迴圈來解決此類問題顯得複雜許多 ( 如第 28~33 行 ), 不過使用迴圈的函式將會比遞迴函式快了許多 ( 您可以將 n 值擴大, 就會感覺到兩者之間的效率差異越來越大 ), 並且不必擔心記憶體空間不足的問題 多載 (overloading) 在傳統的結構化程式設計中 ( 例如傳統 C 程式 ), 一般都不允許出現同名函式, 但這會發生兩個問題 : 1. 由不同人設計的函式, 可能出現同名的現象 例如, 可能有一個 Search 函式是由 A 函式庫引入, 功能是用來找出字串的某個字元 而另一個由 B 函式庫引入的 Search 函式則是用來找出整數陣列的某項資料 由於兩個函式庫由不同人發展, 因此, 在開發函式庫時, 無法預測其他人會使用哪個函式名稱, 而一般人對於函式命名的原則大多相同, 因此容易發生同名的現象 112
57 6.10 多載 (overloading) 2. 針對同樣功能的函式, 必須對於不同資料型態, 取不同的函式名稱 例如, 可能有一個函式名稱為 abs(int x), 用來取整數的絕對值, 它接收的引數為整數型態 但如果要適用於取浮點數絕對值時, 則必須取不同的名稱, 例如 absfloat(float x) 上述兩項問題, 對於發展大型程式非常不利, 而物件導向語言既然是為了解決大型程式的開發問題而設計, 自然必須利用一些機制改善此問題 多載 (overloading) 針對這兩種問題, 物件導向程式設計 ( 例如 C++ 或 Java) 採用下列方式來解決 1. 改以類別來區分, 只要在類別內不出現同名函式即可 ( 不同類別的函式同名則無妨 ), 當然如此做還是可能出現類別名稱相同的問題, 此時, 不同的程式語言則採用不同的機制 例如 :C++ 採用的是 namespace 機制 Java 採用的是 Package 機制來管理 2. 在上述解決方案中, 所謂類別內不允許出現 同名函式, 實際上的規範則是不允許出現 同署名的函式, 因此, 同名但不同署名的函式是允許出現的, 這就是所謂多載 (orverload) 的機制 114
58 6.10 多載 (overloading) 函式的署名 (signature) 回顧函式的定義語法之第一行的函式宣告, 若函式提供了參數, 則如同下列範例 : public static int func1(int n,float b, ) 其中, 函式名稱後面的 () 內是參數串列, 當中宣告了參數的資料型態與名稱, 而所謂函式署名則包含了下列三項元素 : 1. 函式名稱 2. 參數資料型態 3. 參數的個數與順序 多載 (overloading) Java 提供了多載功能, 故一個類別內的函式署名不能相同, 意即函式名稱可以相同, 只要參數的資料型態或個數或順序其中有一項不同即可 如下範例 : class MyClass void show() void show(int n) //void show(int a) 不合法, 因只有參數名稱不同, 但那並非署名的一部分 //int show(int n) 不合法, 因只有回傳值資料型態不同, 但那並非署名的一部分 //int show(int a) void show(double n) void show(int m,int n) //void show(int n,int m) void show(double m,int n) void show(int m double m) 不合法, 原因同上述兩點 不合法, 因只有參數名稱不同, 但那並非署名的一部分 116
59 6.10 多載 (overloading) 筆者的話 法律沒有規定兩個人不能有相同的名字, 所以不同的父母親可能為自己的子女取了相同的名字 ( 例如王建民就不只一個 ) 不過即使是相同名字的兩個人, 其簽名的樣子也不會相同 ( 故文件上的簽名就可以作為區別 ), 而函式利用署名 (signature) 來區分, 大概也是由此而來 多載的用意 多載免除了相同功能卻必須使用不同函式名稱開發的困擾, 如同第三章所提到 String 的 valueof( 原始資料型態參數 ) 函式, 呼叫它時, 引數可以輸入不同的原始資料型態, 其用意都是將該引數轉換為字串, 故功能相同, 不應以不同的函式名稱來命名, 而多載提供了這種功能 多載 (overloading) 例如在 String 類別的說明文件中, 我們可以發現下列關於 valueof method 的宣告語法 :: static String valueof(boolean b) static String valueof(char c) static String valueof(char[] data) static String valueof(char[] data, int offset, int count) static String valueof(double d) static String valueof(float f) static String valueof(int i) static String valueof(long l) static String valueof(object obj) 多載雖然提供了函式命名的方便性, 但我們不應隨意 濫用 多載, 而忽略了函式名稱所代表的重要性 118
60 6.10 多載 (overloading) 例如我們有一些關於幾何圖形的成員變數 length,width,radius, 等等, 並且有計算面積的函式如下, 則可以透過下列兩種方式命名 : class MyClass int calarea(int a,int b)... int calarea(double a,double b)... double calarea(int r)... double calarea(double r)... 合法 class MyClass int calrectarea(int a,int b)... int calrectarea(double a,double b)... double calcirclearea(int r)... double calcirclearea(double r)... 合法且較有擴充性 多載 (overloading) 第一種命名方式, 四個函式共同發生多載現象, 而第二種方式則是上兩個函式發生多載現象, 下兩個函式也發生多載現象 雖然兩者都合法, 但第一種方法, 可能無法再被擴充為計算正方形的面積, 例如再宣告一個 double calarea(double edge) 來計算正方形面積就不合法了 當然, 在這個範例中, 光是由幾何圖形作為類別可能是不足夠的, 我們也可以透過繼承機制將幾何圖形分為更細的矩形 正方形 圓形等子類別來解決相同問題, 由於牽涉的技巧較為複雜, 我們於後面章節再行介紹 120
61 6.10 多載 (overloading) 多載 是實踐物件導向設計的 多型 設計, 多型 (Polymorphism) 又稱為同名異式, 它代表的是使用相同函式名稱, 但可以有不同的函式內容, 所謂 名 指的是函式名稱, 而 式 則是函式內容的敘述群 而事實上, 由於函式內容的敘述群可以不同, 因此功能也可能不同 因為程式語言規範的只能是語法而很難檢測出函式內容究竟提供了什麼樣的服務 多載 (overloading) 但我們一般在使用多載時, 仍以同功能的函式為主要目的, 但同功能並非指的是只有資料型態的不同, 而程式碼完全相同 ; 如果是僅僅資料型態不同, 但程式碼完全相同, 某些程式語言則提供了 樣板 或 泛型 來解決 物件導向設計的 多型 設計, 除了多載之外, 還有改寫 (override) 以及介面等等, 我們將於後面陸續介紹 多載的函式之間, 是否可以互相呼叫呢? 答案是可以的, 因為它們仍是不同的函式, 並且當彼此發生呼叫時, 仍不算是遞迴呼叫, 除非, 它們間接或直接呼叫回原本同署名的函式 122
62 6.10 多載 (overloading) 事實上, 為了切割程式的主要設計, 我們有時也會在多載的函式間進行呼叫, 請見下面的範例 : 觀念範例 6-21 : 釐清多載的設計 範例 6-21:ch6_21.java( 隨書光碟 myjava\ch06\ch6_21.java) /* 檔名 :ch6_21.java 功能 : 函式的多載 */ package myjava.ch06; import java.lang.*; public class ch6_21 public static void main(string args[]) printhello(); // 呼叫第 18~21 行的函式 System.out.println(" "); printhello(2); // 呼叫第 23~37 行的函式 System.out.println(" "); printhello("three"); // 呼叫第 38~44 行的函式 //printhello(2.1); 錯誤的函式呼叫 執行結果 Hello Java Hello Java Hello Java Hello Java Hello Java Hello Java 多載 (overloading) public static void printhello() System.out.println("Hello Java"); public static void printhello(int n) if(n>3) System.out.println("sorry,more than 3!"); return; else if(n<0) System.out.println("sorry,bad command!"); return; for(int i=0;i<n;i++) printhello(); // 呼叫第 18~21 行的函式 public static void printhello(string str1) if(str1=="one") printhello(); // 呼叫第 18~21 行的函式 else if(str1=="two") printhello(2); // 呼叫第 23~37 行的函式 else if(str1=="three") printhello(3); // 呼叫第 23~37 行的函式 else System.out.println("sorry,more than 3 or bad command!"); 124
63 6.10 多載 (overloading) 範例說明 : 函式呼叫會執行的函式如註解所示 而第 15 行的函式呼叫會發生編譯錯誤, 因為編譯器找不到 printhello(double 參數 ) 的函式可以進行呼叫 本章回顧 Java 的類別方法是完成程式邏輯之處, 在本章中, 我們將方法 (method) 大多稱為成員函式 (member function) 或函式 (function) 在 Java 中, 這些方法又可以分為兩種 一種是可以由類別直接執行的 static 方法另一種則是必須由類別產生物件實體後, 由物件執行的方法 126
64 6.11 本章回顧 函式最好具有特定功能 ( 並以該功能來命名函式 ), 並且函式的程式碼應該越簡單越好, 如此才能夠提高程式的可讀性並有利於除錯與日後的維護 函式擁有屬於自己的名稱,Java 透過多載 (overload) 技術, 允許宣告兩個相同名稱的函式, 但其署名不能相同 函式內宣告的變數為 區域變數, 不同函式內可以使用相同的變數名稱, 因為該變數只會在該函式中生效 本章回顧 Java 的函式必定隸屬於某一個類別, 函式擁有屬於自己的名稱, 除非透過多載 (overload) 技術, 否則同一類別不允許宣告兩個相同名稱的函式 除了介紹 函式定義 與 函式呼叫 之外, 我們還介紹了 Java 如何處理函式呼叫的引數傳遞, 依照資料型態的不同, 分為 傳值呼叫 傳參考值呼叫 兩種對於原始資料型態的引數,Java 採用的是傳值呼叫而其他如物件引數 陣列引數則採用傳參考值呼叫, 因為物件變數與陣列變數的本質就是一個參考 128
65 6.11 本章回顧 為了開發樂透開獎程式, 在本章中, 我們介紹了亂數函式 java.lang.math.random(), 它會回傳一個介於 0.0~1.0( 不含 1.0) 的亂數 除此之外, 我們也補充說明了循序搜尋演算法與二分搜尋演算法, 並且 Java 也提供了 Arrays.binarySearch() 函式進行對陣列的二分搜尋 本章回顧 遞迴函式代表函式直接或間接呼叫函式本身, 在許多的問題解決中, 它是一個簡單且直觀的方法 在資料結構的樹狀結構中, 也大量使用遞迴來解答問題 130
66 6.11 本章回顧 筆者的話 函式 (function) 和方法 (method) 在 Java 中是同義的 ( 在 C++, 則兩者仍有區別 ), 因為 Java 規定所有的函式都必定隸屬於某一個類別 事實上, 在 Java 說明文件中, 您只會看到 method 這個字 ( 在 Java 說明文件中,class 只有 fields, methods 與 Constructors 三種成員 ), 而不會看到 function, 本書之所以有時以函式來翻譯 method, 只是為了撰文的方便, 例如 6.9 節的第一行文字, 若將方法取代函式, 則會變成下列文字 : 原文 在前面的章節中, 我們已經練習很多在函式中呼叫另一個函式的方法 以方法取代函式之後 在前面的章節中, 我們已經練習很多在方法中呼叫另一個方法的方法 相信讀者看到取代後的文字, 大概反應都是 不知所云 吧 因此, 在後面的章節中, 當主要內容為講解 method 時, 大多時候將採用函式來稱呼, 但在更後面講解類別應用時 ( 例如視窗元件 AWT 類別 ), 則會盡可能採用 方法 一詞來說明, 而在文字衝突時, 則以 method 來替代 131 本章結束 Q&A 討論時間 132
第1章
第 8 章 函式 1 本章提要 8.1 前言 8.2 如何定義函式 8.3 函式的呼叫和返回 8.4 傳遞陣列 8.5 方法多載 8.6 遞迴 8.7 綜合練習 8.8 後記 2 8.1 前言 每一種高階程式語言都有提供函式 (Function)( 或稱函數 ) 的功能, 以便將經常使用到的程式功能包裝成函式的形式, 如此一來便能反覆地呼叫該函式來完成某件特定工作在高階程式語言中, 副程式 (Subroutine)
Microsoft PowerPoint - java2012-ch12投影片.ppt
第十二章大型程式的發展與常用的類別庫 學習如何分割檔案認識類別庫以及取用類別庫裡的類別建構 package 的階層關係學習 Java 裡常用的類別庫 1 分割檔案的實作 (1/2) 12.1 檔案的分割 以 CCircle 類別為例, 說明分割檔案的實作 1. 依序建立兩個類別檔案, 並置於同一個資料夾內 : 2 分割檔案的實作 (2/2) 12.1 檔案的分割 2. 分別以下列的指令編譯 CCircle.java
Microsoft Word - Prog1-981.docx
5. 變數參照 (Memory Reference) 5.1 指標 (Pointer) (1). 指標 (Pointer) 的基本觀念 特性 內含為一 Memory Address 會因不同的機器而有不同的結果 &" 也是代表變數的位址 例如 : int var1 = 2; cout
全國各級農會第 2 次聘任職員統一考試試題 科目 : 程式設計類別 : 九職等以下新進人員作答注意事項 : 1 全部答案請寫在答案卷內, 如寫在試題紙上, 則不予計分 2 請以黑色或藍色鋼筆或原子筆書寫, 並以橫式書寫 ( 由左至右, 由上而下 ) 一 選擇題 ( 每題 4 分, 共 40 分 )
全國各級農會第 2 次聘任職員統一考試試題 一 選擇題 ( 每題 4 分, 共 40 分 ) 1. 在 Java 語言中, 請問下列何者資料型別的變數, 所需的儲存空間最少? (a) char (b) float (c) double (d) int 2. 請問下列何者非 C 語言的關鍵字 (key word)? (a) const (b) default (c) dynamic (d) continue
Microsoft PowerPoint - java2012-ch08投影片.ppt
第八章認識類別 認識類別的基本架構在類別裡使用資料成員與函數成員學習 this 關鍵字的用法在類別裡設計函數的多載學習如何使用類別裡的公有與私有成員 1 類別的基本概念 每一個 Java 程式, 至少會存在一個或一個以上的類別 類別是由資料成員與函數成員封裝而成 類別內的資料成員稱為 field( 範疇 ) 在 oop 裡, 函數成員是封裝在類別之內 類別是由 資料成員 與 函數成員 封裝而成 2
Microsoft PowerPoint - C-Ch10.ppt
了解陣列元素的位址 陣列 指標的應用 10-1 陣列與指標的關係 可以使用位址運算子 (&) 來查詢陣列中各個元素的位址 &test[0] 這行表示陣列最前面元素的位址 &test[1] 這行表示陣列第二個元素的位址 關於陣列名稱的機制 陣列名稱可以表示陣列最前面元素的位址 #include int main(void) int test[5] = 80,60,55,22,75;
untitled
1 Outline 料 類 說 Tang, Shih-Hsuan 2006/07/26 ~ 2006/09/02 六 PM 7:00 ~ 9:30 聯 [email protected] www.csie.ntu.edu.tw/~r93057/aspnet134 度 C# 力 度 C# Web SQL 料 DataGrid DataList 參 ASP.NET 1.0 C# 例 ASP.NET 立
Microsoft PowerPoint - 第10章.ppt
副程式 通常我們會將重複功能的程式碼, 獨立形成一個固定的程式片段, 讓主程式重複呼吸使用稱為副程式 主程式 開 始 副程式 1 副程式 2 敘述 1 敘述 2 Sub 功能 1( ) : : End Sub Sub 功能 2( ) : : End Sub 輸 出 結 束 主程式與副程式 10-1 副程式 副程式和函式最大的不同處在於 : (1) 副程式並不傳回值 (2) 函式會傳回一個值 假設要讓副程式回傳值,
Microsoft PowerPoint - 12 struct and other datatypes.ppt
第十一章結構與其它資料型態 結構與巢狀結構 結構陣列的各種使用方法 列舉型態 自定的型態別名 typedef 認識結構 使用者自定的資料型態 結構可將型態不同的資料合併成為新的型態 定義結構與宣告結構變數的格式如下 : struct 結構名稱 資料型態成員名稱 1; 資料型態成員名稱 2;... 資料型態成員名稱 n; struct 結構名稱變數 1, 變數 2,, 變數 n; 定義結構與宣告結構變數的語法
Microsoft Word - JAVA Programming Language Homework I ans
JAVA Programming Language Homework I - OO concept Student ID: Name: 1. Which of the following techniques can be used to prevent the instantiation of a class by any code outside of the class? A. Declare
Microsoft PowerPoint - C-Ch08.ppt
函數 8-1 函數 函數 (function) 可以整合某些特定的處理 整合好的處理可以隨時呼叫使用 C 語言的程式本身也是一個函數, 也就是 main() 函數 使用函數可簡化程式 提款的處理 1. 將提款卡插入自動提款機當中 2. 輸入個人密碼 3. 指定提款金額 4. 領取款項 5. 確認款項與提款卡 提款處理 8-2 函數的定義與呼叫 定義函數的語法 : 傳回值的型態函數名稱 ( 引數列表
Microsoft PowerPoint - EmbSys102_JavaOOP [相容模式]
嵌入式系統及實驗 Embedded System and Experiment 詹曉龍 長庚大學電機系 Java 的類別與物件 : 宣告類別 建構子 public class Customer { // Customer 類別宣告 private String name; // 成員資料 private String address; public int age; // 建構子 : 使用參數設定成員資料初始值
第1章
第 15 章 標準類別 1 本章提要 15.1 前言 15.2 基本資料類別介紹 15.3 Integer 類別 15.4 Double 類別 15.5 Float 類別 Long 類別 Short 類別 15.6 數學相關類別 Math 15.7 後記 2 15.1 前言 不同基本資料型別可以互相轉換, 但也只予許由小轉大的情況, 例如 1. byte 轉為 short int long float
C/C++ - 函数
C/C++ Table of contents 1. 2. 3. & 4. 5. 1 2 3 # include # define SIZE 50 int main ( void ) { float list [ SIZE ]; readlist (list, SIZE ); sort (list, SIZE ); average (list, SIZE ); bargragh
第1章
第 9 章 類別 1 本章提要 9.1 前言 9.2 物件導向程式設計基礎 9.3 類別的基本認識 9.4 公有成員與私有成員 9.5 類別變數與類別方法 9.6 進一步認識方法 9.7 進一步認識建構元 9.8 其它 9.9 綜合練習 9.10 後記 2 9.1 前言 物件導向程式設計的特性主要有 : 分而治之 (Divide and Conquer) 資訊隱藏 (Information Hiding)
0 0 = 1 0 = 0 1 = = 1 1 = 0 0 = 1
0 0 = 1 0 = 0 1 = 0 1 1 = 1 1 = 0 0 = 1 : = {0, 1} : 3 (,, ) = + (,, ) = + + (, ) = + (,,, ) = ( + )( + ) + ( + )( + ) + = + = = + + = + = ( + ) + = + ( + ) () = () ( + ) = + + = ( + )( + ) + = = + 0
エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******
******************* * 关于 Java 测试试题 ******************* 問 1 运行下面的程序, 选出一个正确的运行结果 public class Sample { public static void main(string[] args) { int[] test = { 1, 2, 3, 4, 5 ; for(int i = 1 ; i System.out.print(test[i]);
CHAPTER VC#
1. 2. 3. 4. CHAPTER 2-1 2-2 2-3 2-4 VC# 2-5 2-6 2-7 2-8 Visual C# 2008 2-1 Visual C# 0~100 (-32768~+32767) 2 4 VC# (Overflow) 2-1 2-2 2-1 2-1.1 2-1 1 10 10!(1 10) 2-3 Visual C# 2008 10! 32767 short( )
Microsoft PowerPoint - C_Structure.ppt
結構與其他資料型態 Janet Huang 5-1 結構的宣告 struct 結構名稱 struct 結構名稱變數 1, 變數 2,, 變數 m; struct 結構名稱 變數 1, 變數 2,, 變數 m; student; student; 5-2 1 結構變數初值的設定 struct 結構名稱 struct 結構名稱變數 = 初值 1, 初值 2,, 初值 n student="janet","1350901",100,95
新・解きながら学ぶJava
481! 41, 74!= 40, 270 " 4 % 23, 25 %% 121 %c 425 %d 121 %o 121 %x 121 & 199 && 48 ' 81, 425 ( ) 14, 17 ( ) 128 ( ) 183 * 23 */ 3, 390 ++ 79 ++ 80 += 93 + 22 + 23 + 279 + 14 + 124 + 7, 148, 16 -- 79 --
Microsoft Word - CS-981.doc
4. 資料表示法 4.1 十進位與數字系統 (1). 基本觀念 數字系統的觀念 人們習慣以十進位的計量方式來計算 不同的數字系統有二進位 (Binary) 八進位 (Octal) 十進位 (Decimal) 十六進位(Hexadecimal) 二進位 電腦內部用來表達訊號的資料只有兩種符號 : 0 表示沒電,1 表示有電透過多個電路的組合表示出無數符號, 電腦便利用這些符號來表示不同的數字 利用兩條電線可以表示出
C++ 程式設計
C C 料, 數, - 列 串 理 列 main 數串列 什 pointer) 數, 數, 數 數 省 不 不, 數 (1) 數, 不 數 * 料 * 數 int *int_ptr; char *ch_ptr; float *float_ptr; double *double_ptr; 數 (2) int i=3; int *ptr; ptr=&i; 1000 1012 ptr 數, 數 1004
Microsoft PowerPoint - SE7ch05.ppt
第五章陣列 課前指引陣列是一種非常重要的資料結構, 它可以讓程式設計更精簡 Java 也支援陣列, 但 Java 的陣列與早期程式語言 ( 如 C/C++) 的陣列有些不同 Java 的陣列可透過某些方法或屬性進行更多的應用 本章將針對陣列的原理及應用做深入且詳細的說明 章節大綱 5.1 一般程式語言的陣列概觀 5.2 Java 的陣列 5.4 其他類別對於陣列的可用方法 5.5 本章回顧 5.3
運算子多載 Operator Overloading
多型 Polymorphism 講師 : 洪安 1 多型 編譯時期多型 ( 靜態多型 ) function overloading 如何正確呼叫同名的函數? 利用參數個數與型態 operator overloading 其實同 function overloading 執行時期多型 ( 或動態多型 ) 如何正確呼叫不同物件的相同名稱的成員函數 利用繼承與多型 2 子類別與父類別物件間的指定 (assignment)
單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e
Android Studio Debugging 本篇教學除了最基本的中斷點教學之外, 還有條件式中斷的教學 條件式中斷是進階的除錯技巧, 在某些特定情況中, 我們有一個函數可能會被呼叫數次, 但是我們只希望在某種條件成立時才進行中斷, 進而觀察變數的狀態 而條件式中斷這項技巧正是符合這項需求 本教學分兩部分 單步除錯 (Page2~11, 共 10) 條件式中斷點 (Page12~17, 共 6)
untitled
1 Outline 流 ( ) 流 ( ) 流 ( ) 流 ( ) 流 ( ) 狀 流 ( ) 利 來 行流 if () 立 行 ; else 不 立 行 ; 例 sample2-a1 (1) 列 // 料 Console.Write(""); string name = Console.ReadLine(); Console.WriteLine(" " + name + "!!"); 例 sample2-a1
Microsoft PowerPoint - SE7ch07.ppt
第七章物件導向設計 : 類別與物件 課前指引在本章中, 我們將正式進入物件導向程式設計的領域, 雖然我們在前面章節, 已經使用過某些 Java 類別庫的類別或物件 ( 例如 :Math 類別 String 物件 ), 但卻未曾學習如何建立一個物件 ( 事實上建立物件必須先宣告類別 ) 在本章中, 我們將從頭教您如何使用 Java 並以物件觀點設計程式, 逐漸體驗物件導向程式設計帶來的好處, 尤其是在發展中大型專案時,
Microsoft PowerPoint - ch4.pptx
.NET 程式設計入門 ( 使用 C#) 1 Outline 類别與物件 欄位與屬性 方法 靜態成員 方法多載 建構式 遞迴 2 命名空間 (1) 使用命名空間的好處可以將功能類似的類別組織在一起 命名空間允許巢狀的結構, 形成階層式的架構, 更容易分類管理 若在同一個程式檔中宣告二個名稱一樣的類別時, 編譯會發生錯誤, 我們可以利用命名空間來解決此問題 利用 using 關鍵字來指定需要的命名空間
Microsoft Word - ACL chapter02-5ed.docx
第 2 章神奇的質數 2.1.1 什麼是質數 1 1 1 打下好基礎 - 程式設計必修的數學思維與邏輯訓練 1 1 0 10 2 3 5 7 4 6 8 9 10 4 10000 1229 1000 168 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131
C/C++基礎程式設計班
C/C++ 基礎程式設計 我們必須讓小事也令人難忘 We ve got to make the small things unforgettable. -Steve Jobs 函式 (Function) 講師 : 張傑帆 CSIE NTU 課程大綱 函式概論 變數類型 - 全 / 區域變數 函式中以指標當參數 傳遞陣列參數 把程式拆成多個檔案 函式 (Function) 包函許多程式碼的一行程式 (
Microsoft PowerPoint - 04-array_pointer.ppt
Array 與 Pointer Array Dynamical Memory Allocation Array( 陣列 ) 陣列是用來存放同樣型態的資料陣列的大小必須在程式中預先設定在程式執行中, 陣列的大小無法改變陣列中的資料是透過索引 (index) 來存取 一維陣列的宣告 type array_name[array_size]; int iarray[100]; /* an integer array
Microsoft PowerPoint - B9-2.pptx
單元名稱 : 9 三角函數的積分 教學目標 : 使學生了解三角函數的積分 三角函數積分的類型及一些積分技巧 學習時數 : 約一小時 教學內容 :. [ 第一類型 ] 六個三角函數本身的積分. [ 第二類型 ] sin n 及 os n 的積分 sin os m n. [ 第三類型 ] 的積分 4. [ 第四類型 ] n 及 ot n 的積分 5. [ 第五類型 ] n 及 s n 的積分 m 6.
Microsoft Word - 第3章.doc
Java C++ Pascal C# C# if if if for while do while foreach while do while C# 3.1.1 ; 3-1 ischeck Test() While ischeck while static bool ischeck = true; public static void Test() while (ischeck) ; ischeck
主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new
ListView 自訂排版 主程式 : public class Main3Activity extends AppCompatActivity { ListView listview; // 先整理資料來源,listitem.xml 需要傳入三種資料 : 圖片 狗狗名字 狗狗生日 // 狗狗圖片 int[] pic =new int[]{r.drawable.dog1, R.drawable.dog2,
資料結構之C語言重點複習
鏈結串列自編教材 ( 一 ) 本教材 ( 一 ) 目標問題 : 每次以亂數產生一 [0,1000] 之整數值, 若該值 >100, 則以同方式繼續產生下一亂數值, 若該值
星星排列 _for loop Protected Sub Page_Load(ByVal sender As Object, ByVal e As Dim h As Integer = 7 'h 為變數 ' Dim i, j As Integer For i = 1 To h
資訊系統與實習 製作 : 林郁君 一 2009.09.28 9X9 'button 被按下後 ' Dim i, j As Integer For i = 1 To 9 'i 從 1 到 9' For j = 1 To 9 'j 從 1 到 9' If j * i < 10 Then ' 如果 j 乘上 i 是為個位數 ' Response.Write(i & "*" & j & " =" & i *
Python a p p l e b e a r c Fruit Animal a p p l e b e a r c 2-2
Chapter 02 變數與運算式 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.2 2.2.1 2.2.2 2.2.3 type 2.2.4 2.3 2.3.1 print 2.3.2 input 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 + 2.4.6 Python Python 2.1 2.1.1 a p p l e b e a r c 65438790
Microsoft PowerPoint - 13_ClassAndObj.ppt
Visual Basic 2005 (VB.net 2.0) 程式設計 講師 : 戴志華 [email protected] 國立台灣大學電機工程研究所 第十三章 物件與類別 物件與類別 物件導向程式設計 物件與類別的建立 物件與類別 物件 (object) Ex. 人 屬性 (property) 身高 體重 血型 方法 (method) 走路 跑步 訊息 (message) 交談 事件
Microsoft Word - ch04三校.doc
4-1 4-1-1 (Object) (State) (Behavior) ( ) ( ) ( method) ( properties) ( functions) 4-2 4-1-2 (Message) ( ) ( ) ( ) A B A ( ) ( ) ( YourCar) ( changegear) ( lowergear) 4-1-3 (Class) (Blueprint) 4-3 changegear
untitled
1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override
Microsoft PowerPoint - 11_Templates.ppt
1 1. 上機考 20% 期末考 6/23( 四 ) 晚 6:30~8:30 範圍 : 第 7, 8, 9, 10 章實習內容 按座位坐, 隨機抽兩題 2. 紙上測驗 20% 6/21( 二 ) :9:30~11:00 課本 7-11, 13 章內容 2 第 11 章樣版 (Templates) 11.1 簡介 11.2 函式樣版 11.3 多載函式樣版 11.4 類別樣版 11.5 類別樣版與無型
Microsoft PowerPoint - ch04_AEL0080.ppt
4 選擇 在正常的情況下, 電腦程式的執行是以敘述的排列次序逐步處理的 使用控制架構 (control structures) 可以改變這種既定的先後次序, 讓程式得以進行更複雜的運算, 或以更簡潔的指令來實現演算法 1/42 選擇 4.1 演算法的描述方式 4.2 變數的運用範圍 (Scope of variables) 4.3 if- 敘述 4.4 巢狀 if- 敘述 (Nested if statements)
Microsoft PowerPoint - java2012-ch13投影片.ppt
第十三章例外處理 瞭解什麼是例外處理認識例外類別的繼承架構認識例外處理的機制學習如何撰寫例外類別 1 例外的基本觀念 在撰寫程式時常見的幾種情況 : (1) 要開啟的檔案並不存在 (2) 存取陣列時, 陣列的索引值超過陣列容許的範圍 (3) 原本預期使用者由鍵盤輸入的是整數, 但使用者輸入的卻是英文字母 這類不尋常的狀況稱為 例外 (exception) 在 Java 中, 所有的例外都是以類別的型態存在
Microsoft PowerPoint - Fig03_Stack.ppt [相容模式]
四 堆疊與佇列 (Stack & Queue) 4-. 串列及鏈結串列 4-. 用陣列結構實作堆疊 4-3. 用鏈結串列實作堆疊 4-4. 堆疊的應用 4-5. 佇列 4-6. 用陣列結構實作佇列 4-7 7. 用鏈結串列實作佇列 堆疊的基本觀念. 定義 : 4- 堆疊 當將東西疊成一堆, 而取用的時候由上方來取出. 特性 : 先進後出, 後進先出 ( 號球先放, 但 3 號球會先拿出 ) 3 3
Microsoft PowerPoint - 13_指標、資料傳遞2.pptx
1 2 指標 Lecture 13 指標函式呼叫的資料傳遞 (III) 傳址指標與陣列 Pointer 3 4 指標 / 指位器 (Pointer) 變數 int a; 整數型別, 名稱為 a 變數是為了使用記憶體資源來儲存資料與進行運算 所有的變數都佔有記憶體空間 記憶體 可視為一個很大的一維陣列, 單位是 byte 問題 一個 4KB 的電腦, 其記憶體位置 ( 編號 ) 從 0 至? 4 x
Microsoft PowerPoint - SE7ch02.ppt
第二章 Java 從零開始 (Java 程式的基本結構 ) 課前指引在本章中, 我們將透過一個非常簡單的 Java 程式來說明 Java 的程式結構 章節大綱 2.1 最簡單的 Java 程式範例 2.2 註解 (comment) 2.6 Java 程式的進入點 main( ) 2.7 Java 的敘述 2.3 package 區 2.4 import 區 2.8 println() 輸出方法的簡易使用法
Java 程式設計初階 第 5 章:基本輸出入 & 流程控制
Java 程式設計 標準輸出入與流程控制 本章大綱 標準輸出入 (Standard I/O) 分支 (Branch) if ~ else switch ~ case 迴圈 (Loop) for while do ~ while 中斷指令 break continue 總整理 標準輸出 定義 : 將資料印到螢幕上 Java 標準輸出指令 System.out.println( 資料 ) 將資料印出後換行
Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc
References (Section 5.2) Hsuan-Tien Lin Deptartment of CSIE, NTU OOP Class, March 15-16, 2010 H.-T. Lin (NTU CSIE) References OOP 03/15-16/2010 0 / 22 Fun Time (1) What happens in memory? 1 i n t i ; 2
Chapter 9: Objects and Classes
Fortran Algol Pascal Modula-2 BCPL C Simula SmallTalk C++ Ada Java C# C Fortran 5.1 message A B 5.2 1 class Vehicle subclass Car object mycar public class Vehicle extends Object{ public int WheelNum
第1章
第 7 章 字串 1 本章提要 7.1 前言 7.2 類別與物件 7.3 String 類別 7.4 StringBuffer 類別 7.5 綜合練習 7.6 後記 2 7.1 前言 Java 用 String 類別 (Class) 來處理字串, String 類別是 Java 類別庫內建的類別, 它是一堆已經寫好的程式, 我們可以直接拿來使用字串很像字元型別的一維陣列, 字串裡能存放的資料都屬於字元性質,
Microsoft Word - DataStruct-981.doc
4. 堆疊與佇列 (Stack and Queue) 4. Stak (). 基本觀念 定義 : 當將東西疊成一堆, 而取用的時候由上方來取出 特性 : 先進後出, 後進先出 ( 號球先放, 但 3 號球會先拿出 ) 2 3 3 2 (2). Stack 的運算 基本運算 push: 將資料放入堆疊 pop: 將資料由堆疊最頂端取出一個 TopItem: 位於堆疊中最上面的一個資料 IsEmpty:
<4D F736F F D203938BEC7ACECBCD2C0C0B8D5A8F7AEE6A6A1C0C92DB57BA6A1B35DAD705FA6B3B8D1B5AA5F2E646F63>
全國高級中等學校 98 學年度商業類科學生技藝競賽 程式設計 職種學科模擬試卷 選手證號碼 : 姓名 : 注意事項 : 請將答案劃記於答案卡, 未依規定劃記者不予計分 試題說明 : ( 選擇題每題 4 分, 共 100 分 ) ( A ) 1. 在 ASCII Code 的表示法中, 下列大小之關係何者為錯誤? (A) A>B>C (B) c>b>a (C) 3>2>1 (D) p>g>e ( D
Microsoft Word - CPMidTerm2011SpringSolution
通識計算機程式設計期中考參考解答, 4/22/2011 1. (a) 宣告 int 變數 k, bool 變數 b, double 變數 x (3%) 答 : int k; bool b; double x; (b) 在螢幕顯示一行字, 要求使用者輸入一個整數 (3%) 答 : Console.WriteLine(" 輸入一個整數 "); (c) 自鍵盤讀入一個整數., 並將其值存入已宣告之 int
10-2 SCJP SCJD 10.1 昇陽認證 Java 系統開發工程師 的認證程序 Java IT SCJD
10 SCJD 簡介 Java 10-2 SCJP SCJD 10.1 昇陽認證 Java 系統開發工程師 的認證程序 Java IT SCJD 10 SCJD 10-3 Java Java SCJD 7 Swing RMI 10.1.1 The Assignment The Essay 9 10 10-4 SCJP SCJD 90 10.1.2 SCJP Java 90 120 Swing 10
EJB-Programming-4-cn.doc
EJB (4) : (Entity Bean Value Object ) JBuilder EJB 2.x CMP EJB Relationships JBuilder EJB Test Client EJB EJB Seminar CMP Entity Beans Session Bean J2EE Session Façade Design Pattern Session Bean Session
The Embedded computing platform
嵌入式系統及實驗 Embedded System and Experiment 詹曉龍 長庚大學電機系 Java 的類別與物件 : 宣告類別 建構子 public class Customer { private String name; private String address; // Customer 類別宣告 // 成員資料 public int age; // 建構子 : 使用參數設定成員資料初始值
Microsoft Word C-A卷.docx
100 學年度資訊學院程式設計會考 (C) 101/05/5 題組 :A 選擇題及填充題, 請在答案卡上作答, 實作題請填寫於答案卷上, 並於實作題上方填寫班級 姓名 學號 一 選擇題題目 1. unsigned char 的最大值 (a) 127 (b) 255 (c) 512 (d) 1023 2. 下列何者為正確的變數名稱? (a) Android (b) C++ (c) I Phone (d)
第二章 簡介類別
Instructor 曾學文 [email protected] http://wccclab.cs.nchu.edu.tw/www/index.php/c ourse/2017-03-20-07-38-21/105-105-2-c TA 王昱彬 第一章概觀 C++ 1-2 二種版本的 C++ 1-5 初步檢視類別 1-1 何謂物件導向程式設計 1-8 C++ 的關鍵字 1-2 二種版本的 C++
01 用 ActionScript 3.0 開始認識 Flash CS3 Flash 是應用在網路上非常流行且高互動性的多媒體技術, 由於擁有向量圖像體積小的優點, 而且 Flash Player 也很小巧精緻, 很快的有趣的 Flash 動畫透過設計師的創意紅遍了整個網際網路 雖然很多人都對 Fl
01 用 ActionScript 3.0 開始認識 Flash CS3 Flash 是應用在網路上非常流行且高互動性的多媒體技術, 由於擁有向量圖像體積小的優點, 而且 Flash Player 也很小巧精緻, 很快的有趣的 Flash 動畫透過設計師的創意紅遍了整個網際網路 雖然很多人都對 Flash 可以做精美的網路動畫並不陌生, 但是實際上 Flash 不僅如此, 只要搭配 ActionScript
投影片 1
資料庫管理程式 ( 補充教材 -Part2) 使用 ADO.NET 連結資料庫 ( 自行撰寫程式碼 以實現新增 刪除 修改等功能 ) Private Sub InsertButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InsertButton.Click ' 宣告相關的 Connection
Matlab 程式設計第二版洪維恩編著旗標出版 第八章撰寫底稿與函數習題參考答案 8.1 撰寫底稿 1. 請參考 節, 利用 M 檔案的底稿繪出 r log( t) 的極座標圖, 繪圖範圍請用 0.01 t 6, 繪圖點數 100 點 M 檔案名稱請取名為 ex8_1.m Ans: %
Matlab 程式設計第二版洪維恩編著旗標出版 第八章撰寫底稿與函數習題參考答案 8.1 撰寫底稿 1. 請參考 7.1.1 節, 利用 M 檔案的底稿繪出 r log( t) 的極座標圖, 繪圖範圍請用 0.01 t 6, 繪圖點數 100 點 M 檔案名稱請取名為 ex8_1.m % ex8_1.m t=linspace(0.01,6*pi,100); r=log(t); polar(t,r)
任務二 : 產生 20 個有炸彈的磚塊, 放在隨機的位置編輯 Block 類別的程式碼 import greenfoot.; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) Write a description of class
踩地雷遊戲 高慧君南港高中 開啟專案 MineSweep 任務一 : 產生 30X20 個磚塊編輯 Table 類別的程式碼 import greenfoot.; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.arraylist; Write a description of class MyWorld
OOP with Java 通知 Project 4: 4 月 19 日晚 9 点
OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d
Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0,
http://debut.cis.nctu.edu.tw/~chi Java java.lang.math Java Java.util.Random : ArithmeticException int zero = 0; try { int i= 72 / zero ; }catch (ArithmeticException e ) { // } 0, : POSITIVE_INFINITY NEGATIVE_INFINITY
Microsoft Word - C-pgm-ws2010.doc
Information and Communication Technology 資訊與通訊科技 Loops (while/for) C 廻路 姓名 : 班別 : ( ) CS C Programming #1 Functions 函數 : 1 若 n=14, 求以下表示式的值 Expressions 表示式 Value 值 Expressions 表示式 Value 值 A 20 2 * (n /
Microsoft PowerPoint - 05-func.ppt
函式 (Functions) 用途 定義語法 使用前必須先宣告 呼叫 傳回值的資料型態 參數列 引數的傳遞方式 陣列參數 預設的引數值 不定數目的參數 return 敘述 遞迴函式 行間函式 處理指令行的選項 函式指標 與其它語言寫成的函式連結 Function - 1 函式的用途 程式碼的再利用 (code reuse) 便利模組化設計的 implementation 便利程式的維護 便利程式的移植
C/C++ Programming
265 第九講 結構 講師 : 李根逸 (Ken-Yi Lee), E-mail: [email protected] 266 課程 大綱 結構 (struct) 結構宣告 [P.267] 結構定義 [P.268] 結構變數宣告 [P.269] 結構變數的初始化 [P.272] 存取結構成員 [P.244] 傳送 大型資料型態參數 [P.277] 267 結構宣告 結構是 一種衍 生的 自訂資料型態,
第3章.doc
3 3 3 3.1 3 IT Trend C++ Java SAP Advantech ERPCRM C++ C++ Synopsys C++ NEC C C++PHP C++Java C++Java VIA C++ 3COM C++ SPSS C++ Sybase C++LinuxUNIX Motorola C++ IBM C++Java Oracle Java HP C++ C++ Yahoo
WWW PHP
WWW PHP 2003 1 2 function function_name (parameter 1, parameter 2, parameter n ) statement list function_name sin, Sin, SIN parameter 1, parameter 2, parameter n 0 1 1 PHP HTML 3 function strcat ($left,
Microsoft PowerPoint - SE7ch03.ppt
第三章變數與運算式 課前指引在 Java 語言中, 資料以變數來加以儲存, 資料運算則是利用 Java 所提供的眾多運算子來處理資料 運算子與運算元將組合成運算式, 而運算式只要在結尾加上一個 ; 就形成了最簡單的單一敘述 章節大綱 3.1 變數與資料型態 3.2 資料輸入 3.4 資料型態的轉換 3.5 本章回顧 3.3 運算式 ( 運算子及運算元 ) 備註 : 可依進度點選小節 3.1 變數與資料型態
<4D F736F F D20B3AFABD8EA4D2DB9EFBAD9A668B6B5A6A1AABA652D68ABEDB5A5A6A15FA4555F>
對稱多項式的 h恆等式 ( 下 ): 將 h 用 的行列式表示 陳建燁 臺北市立第一女子高級中學數學教師 壹 前言 : 關於對稱多項式, 有一個很重要的事實, 稱為 對稱多項式的基本定理, 簡單地說, 即任何 元 (,,, ) 的對稱多項式, 總是可以寫成 個基本對稱多項式 ( 即,,, ) 的多項式 ( 參考資料 [4]) 例如: ( ) ( ) [ (,, )] (,, ) 那 麼, 既然 h(,,,
PowerPoint Presentation
第六章簡介運算子超載 (Operator Overloading) 6-1 運算子超載的基礎 6-2 超載二元運算子 6-3 超載邏輯與關係運算子 6-4 超載一元運算子 6-5 使用夥伴函數 6-6 細部檢視指定運算子 6-7 超載註標運算子 6-1 運算子超載的基礎 甚麼是運算子超載? 讓運算子 ( 符號 ) 有不同的意義 EX: 運算子的預設意義 ( 以 + 與 = 為例 ) class frac
内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌
语 言 程 序 设 计 郑 莉 胡 家 威 编 著 清 华 大 学 逸 夫 图 书 馆 北 京 内 容 简 介 本 书 是 一 本 关 于 语 言 程 序 设 计 的 教 材, 涵 盖 了 语 言 的 基 本 语 法 和 编 程 技 术, 其 中 包 含 了 作 者 对 语 言 多 年 开 发 经 验 的 总 结, 目 的 是 让 初 学 的 读 者 感 受 到 语 言 的 魅 力, 并 掌 握 语
Microsoft PowerPoint - C++類別.ppt
C++ 的類別 (Class) 類別 (Class) 是一種資料型態, 可用來宣告物件 類別內含有資料成員 (Data member) 和成員函式 (Member function) 類別中不論是 Data Member 或 Member function 都可在 public 區或 private 區宣告 因 OOP 特性之一是隱藏資料, 一般會將 data member 以 private 方式宣告保護起來,
第一篇文概說第七章公文的用語及標點符號公本篇內容 第一章 緒論 第二章 公文的意義 第三章 公文與高 普 特各類考試 第四章 公文程式之意義及演變 第五章 公文之分類及其行文系統 第六章 公文之結構與行款 第一篇 第一章緒論 003 第一章緒論 等 等 004 最新應用公文 第一篇 第二章公文的意義 005 第二章公文的意義 第一節 一 須為公務員製作之文書 二 須為公務員 職務上 製作之文書 006
CC213
: (Ken-Yi Lee), E-mail: [email protected] 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,
Microsoft PowerPoint - 07-overloaded.ppt
Overloaded Functions 前言 處理多載函式宣告的規則 處理多載函式呼叫的規則 多載函式與 scope 函式呼叫的議決 前言 C 語言規定 : 函式的名稱不可相同 這樣的規定使得我們必須為功能相近但參數型態相異的函式取不同的名稱, 譬如 : int imax (int, int); double dmax (double, double ); // max function for
<4D F736F F D DA5BFA6A1C476C1C92DBEC7ACECB8D5A8F728B57BB35D292E646F63>
全國高級中等學校 106 學年度商業類科學生技藝競賽 程式設計 職種 學科 試卷 選手證號碼 ( 崗位編號 ): 姓名 : 注意事項 : 請將答案劃記於答案卡, 未依規定劃記者不予計分 試題說明 :( 選擇題共 25 題每題 4 分, 答錯不倒扣, 共 100 分 ) ( )1. 執行以下 Visual Basic 程式片段, 其結果為何?(A) 15 (B) 12 (C) 7 (D) 3 Dim
!249 第 八講 進階指標 講師 : 李根逸 (Ken-Yi Lee),
249 第 八講 進階指標 講師 : 李根逸 (Ken-Yi Lee), E-mail: [email protected] 250 課程 大綱 陣列的複製 [P.252] 字串的特殊性 [P.255] const 修飾字 [P.256] 指標陣列 [P.257] 字串陣列 [P.258] 指標與 二維陣列 [P.260] 動態記憶體配置與釋放 C 語 言中動態記憶體的配置 [P.266] C 語
Microsoft PowerPoint - ch1.pptx
1 變數 資料型別 變數宣告及使用 型別轉換 運算子 常數 列舉型別 結構型別 亂數 課後練習 2 何謂變數 變數 是用來請電腦幫忙記住某些我們需要的東西 變數宣告 變數在使用之前, 必須先告訴電腦要預先準備多大的空間來存放這個變數的內容, 這樣的步驟稱之為 宣告 資料型別 利用 資料型別 來描述所需要的空間大小 3 開頭第一個字必須為 A Z a z 或 _ ( 底線 ) 不允許數字 0 9 當做變數的開頭
第 15 章遞迴呼叫 本章學習目標 說明遞迴函式呼叫概念 透過範例介紹遞迴函式呼叫與應用 本章重點概述 本章主要介紹如何使用遞迴函式呼叫進行計算 1
第 15 章遞迴呼叫 本章學習目標 說明遞迴函式呼叫概念 透過範例介紹遞迴函式呼叫與應用 本章重點概述 本章主要介紹如何使用遞迴函式呼叫進行計算 1 15.1 何謂遞迴函式 遞迴就是函數自己呼叫自己 如果一個問題的解決可以拆成多個相同的小問題, 這 樣的問題就很適合使用 以 階層數 計算的問題為例, 若階層數的函式為 fac(n) = n (n-1) (n-2) 1, 如果不使用遞迴呼叫時我們可以把式子寫成下列形式,
