260 likes | 443 Views
方法或函數. 函數( Function )就像構成完整軟體系統的小元件,根據系統的需求,分別設計出各種小元件,再組合成為完整的軟體系統。 在 Java 裡面的函式 叫做 『 方法 』(method) 已經全部用物件的方式包裝起來. 函數的格式與類型:. 函數. 定義 可重複使用的程式碼片段 格式. 存取範圍. 函數特性. static final abstract native synchronized. public protected ( 空白 ) private. 函數傳回型態. 函數名稱. ( 參數宣告 );.
E N D
函數(Function)就像構成完整軟體系統的小元件,根據系統的需求,分別設計出各種小元件,再組合成為完整的軟體系統。 在 Java 裡面的函式 叫做『方法』(method) 已經全部用物件的方式包裝起來 函數的格式與類型:
函數 • 定義 • 可重複使用的程式碼片段 • 格式 存取範圍 函數特性 static final abstract native synchronized public protected (空白) private 函數傳回型態 函數名稱 (參數宣告); 範例:public static void main (String[] args);
建立與呼叫方法 import java.util.*; public class DATE1 { static void output( ) //顯示時間的函數 { Date now = new Date( ); System.out.println("現在時間是:"+now); } public static void main(String args[]) { output( ); //呼叫函數 } } • 顯示時間的程式碼內容如下(請比較兩種的寫法): import java.util.*; public class DATE1 { public DATE1 {} public void output( ) //顯示時間的函數 { Date now = new Date( ); System.out.println("現在時間是:"+now); } public static void main(String args[]) { DATE1 a=new DATE1() a.output( ); //呼叫函數 } }
方法的型態 (傳回值型態) 引數 (Arguments) 參數 (Parameters) 方法: 呼叫: 傳回值 傳回一個常數 傳回一個運算式 沒有傳回值 • 方法的相關名詞(注意 參數與引數 ) return的用法
函數練習 import java.io.*; public class PowerTest {int x,y,z; public void input() throws IOException { System.out.print("請輸入x:"); InputStreamReader in=new InputStreamReader(System.in); BufferedReader buffer1=new BufferedReader(in); String str1=buffer1.readLine(); x=Integer.parseInt(str1); str1=buffer1.readLine(); y=Integer.parseInt(str1); } static long power(long a, long b) { long result = 1; for (long i=1; i<=b; i++) { result *= a; } return result; } public void process() { z=power(x, y); } public void output() { System.out.println(" x^y = " +z); } public static void main(String[] args) { PowerTest a=new PowerTest(); a.input(); a.process(); a.output(); } } • 請設計出一個可以計算次方的函式 • static long power(long a, long b)
函數練習 import java.util.*; public class WEEK { String W=new String(); Calendar rightNow; public WEEK() { } public String getW() { return W; } public void input() { rightNow= Calendar.getInstance( ); } public void process() { String str1[]={"日","一","二","三","四","五","六"}; int day=rightNow.get(rightNow.DAY_OF_WEEK);//傳回1->7,1表星期日2表星期一 W= str1[day-1]; } public void output() { System.out.println(getW());} public static void main(String args[]) { WEEK a=new WEEK(); a.input(); a.process(); a.output(); } } • 顯示今天是星期幾的程式碼如下:
日期與時間 class Time0 { String W=new String(); int y,m,d,h,min,sec,msec; long t1; Calendar cal; public Time0() { } public void input() { cal= Calendar.getInstance( ); } public void process() { y = cal.get(Calendar.YEAR); m = cal.get(Calendar.MONTH) + 1; d = cal.get(Calendar.DATE); h = cal.get(Calendar.HOUR_OF_DAY); min = cal.get(Calendar.MINUTE); sec = cal.get(Calendar.SECOND); msec= cal.get(Calendar.MILLISECOND); t1 = System.currentTimeMillis(); } public void output() { System.out.print("今天是 "); System.out.println(y +"年"+ m +"月"+ d +"日"); System.out.print("現在是 "); System.out.println(h +"點"+ min +"分"+ sec +"秒"); System.out.println("1990年01月01日00時00分00秒到現在"+t1 +"秒/1000"); } public static void main(String args[]) { Time0 a=new Time0(); a.input(); a.process(); a.output(); } }
Return:函數傳回資料到主程式時使用 public class SEARCH { String chi=new String(); String eng=new String(); public SEARCH() {}; public void setC(String c) { chi=c; } public String getE() { return eng; } public void Find() { String lista[] ={"蘋果", "葡萄", "柳橙", "香蕉", "番茄"}; String listb[] ={"apple", "grape", "orange", "banana", "tomato"}; for(int i=0;i<lista.length;i++) { if(chi.equals(lista[i])) { eng = listb[i]; break; } } } public void output() { System.out.println("柳橙英文單字是:"+getE()); } public static void main(String args[]) { SEARCH a=new SEARCH(); a.setC("柳橙"); a.Find(); a.output(); } }
傳值呼叫(call by value)是指在呼叫函數時,只將變數值傳遞給函數,而函數取得參數值後再進行運算,當變數值改變時,與主程式中的變數完全無關。 傳值呼叫程式碼範例 public class CALLBYVALUE { static void test_value(int x,int y) { x=x+10; y=y+50; System.out.println("呼叫函數中 x="+x+" y="+y); } public static void main(String args[]) { int x=5,y=10; System.out.println("呼叫函數前 x="+x+" y="+y); test_value(x,y); //呼叫函數 System.out.println("呼叫函數後 x="+x+" y="+y); } }
傳址呼叫: • 所謂傳址呼叫(call by address)是指在呼叫函數時,將變數對應的記憶體位置傳遞給函數,而函數會根據記憶體位置取得參數的值。 • 主程式呼叫 add_value 函數時,會將變數 x 的位址傳遞給函數,因此,add_value 中的變數 xlist 使用的位址將與主程式的 x 相同,當函數中 xlist 的值改變時,主程式中 x 變數的值也會跟著改變。(請參考SORT 類別)
利用傳址呼叫傳遞參數的程式碼: public class CALLBYADDRESS { String str1 =" "; int x[]={55,80,23,30,20,75}; public CALLBYADDRESS() {} public void add_value(int[] y) { for(int i=0;i<y.length;i++) { y[i]=y[i]+10; } } public void out() { for(int i=0;i<x.length;i++) { str1=str1+x[i]+","; } System.out.println(str1); } public static void main(String args[]) { CALLBYADDRESS a=new CALLBYADDRESS(); a.out(); a.add_value(); //呼叫函數 a.out(); } }
包裝在java.Math.* 類別的方法 Math底下的常數
簡單的數學函數練習: • 請利用 Math 提供的數學函數,設計一個程式,讓操作者輸入一數值 n 時,會在螢幕上顯示此數值的 • 絕對值 • 指數 • 平方根 • 自然對數。 問題解析與程式設計: • 運用下列的數學函數來計算此例題 • 絕對值 Math.abs(n) • 指數 Math.exp( n) • 平方根 Math.sqrt(n ) • 自然對數 Math.log(n )
import java.io.*; public class MATHFUNCTION { public static void main(String args[]) throws IOException { String s; InputStreamReader stream=new InputStreamReader(System.in); BufferedReader buffer=new BufferedReader(stream); System.out.print("請輸入一個數值:"); s=buffer.readLine(); double n=Double.parseDouble(s); System.out.println(n+" 絕對值函數 "+Math.abs(n)); System.out.println(n+" 指數函數 "+Math.exp(n)); System.out.println(n+" 平方根函數 "+Math.sqrt(n)); System.out.println(n+" 自然對數函數 "+Math.log(n)); } }
樂透彩的隨機變化: • 撰寫一個預估樂透彩開獎號碼程式,其號碼是 1~42之間的數字,且會自動產生 6 個隨機號碼。 問題解析與程式設計: • 建立一個random_num (n)函數,利用Math提供的Math.random() 隨機函數,自動產生n個隨機數字。 • v=(int)(Math.random()*42)+1; //產生一個1~42的隨機數字 • 將下一頁的程式修改成可以自行檢驗是否有重覆的數字出現.
傳遞參數: public class Lotter { String str1=new String(); public Lotter() {} public void Creat(int n) { int v; for(int i=0;i<n;i++) //產生一個1~42的隨機整數值 { v=(int)(Math.random()*42)+1; str1=str1+v+","; } } public String getS() { return str1; } public static void main(String args[]) { System.out.println("預估樂透彩開獎號碼:"); Lotter a=new Lotter(); a.Creat(6); //呼叫函數 傳遞參數 System.out.println(a.getS()); } }
從命令列傳入的引數 Main 函數 /*用程式裡的 main() 方法的前頭都冠上一個 static 關鍵字,表 示不須建立物件就可執行 main() 方法。*/ public class Command { public static void main(String[] args) { for (int i=0; i<args.length; i++) System.out.println("arg["+i+"]="+args[i]); } } 【執行結果】 ch06> javac Command.java ←┘ [註]編譯命令列 ch06> java Command 2003 1 23 ←┘ [註]執行命令列 args[0]=2003 [註]第一個引數 args[1]=1 [註]第二個引數 args[2]=23
函數多型 • 多載與多型: 多載(overloading)就是多型的一種應用。 • 使用不同的參數項目呼叫相同名稱的函數時,會自動執行對應的程式碼: • 以下就是三個同名函數的函數程式碼: static int mf (int x) //第一個mf函數 { return x; } static int mf(int x,int y)//第二個mf函數 { return x+y; } static int mf(int x,int y,int z)//第三個mf { return x+y+z; } int v1=mf(10); int v2=mf(10,20); int v3=mf(10,20,30);
檢查身份證字號 身份證字號的每一欄含義為 1.地區欄 : A~Z,A 轉換為 10,B 為 11,C 為 12 等。 2.性別欄 : 1 為男性,2 為女性。 3.流水編號 : 7 位數字。 4.檢查號碼 : 欄位 1~9 乘上加權數之總和,除於 10 之餘數,以 10 減之,即為檢查號碼。 例如: 例如: D 2 1 2 3 4 5 6 7 1 3 * * * * * * * * * * 1 9 8 7 6 5 4 3 2 1 ────────────────────── 1 +27 +16 + 7 +12 +15 +16 +15 +12 +7 = 128 其和 128 取個位數 8,以 10 減之,為 2。即檢查號碼為 2,故完整之身份證代號為 D212345672。請設計一個程式檢查輸入的身份證代號是否正確。
遞迴程序 • 所謂遞迴(Recursion)方法是指在方法中呼叫自己的方法。 • 遞迴的方法一定要有終止條件,否則將陷入無窮呼叫,最終導致資源不足或當機
階乘函數(factorial)的遞迴函數: //遞迴階乘函數 public class F { static int F(int n) { if(n==1) { return 1; } else { return (n * F(n-1)); } } public static void main(String[] args) { System.out.println(F(6)); } } //n!=n*(n-1)*(n-2)*………………*1 //n!=n*(n-1)! 在主程式中輸入程式碼: //呼叫遞迴階乘函數 a = F(5); System.out.println(a);
最大公因數與最小公倍數: • 利用遞迴的方式,撰寫一程式,當操作者輸入兩個數值後,會在螢幕上顯示兩數值之最大公因數hcf和最小公倍數lcm。 • 例如:輸入168和70,則計算出最大公因數為14,最小公倍數為840。
hcf最大公因數解析: • 在 hcf() 函數中應用交換和遞迴的方式,兩數相除餘數為0的狀態,求得最大公因數。 • 做交換的動作的程式碼如下: //當S<M,則做交換的動作 if( S < M ) { temp = S; S = M; M =temp; } • 做遞迴的動作,求得最大公因數的程式碼如下: //x1和x2做遞迴的動作,求得最大公因數 if(( S % M ) ==0) return (M); else return (hcf ( M , S%M )); lcm最小公倍數解析: • 在 lcm() 函數中將兩數相乘後,再除以最大公因數,則得其值為最小公倍數=S*M/hcf。 • return (y1*y2)/hcf(y1,y2);
HCFLCM完整程式碼: public class HCFLCM { public HCFLCM() {} public int hcf(int S,int M) //建立hcf函數 { int temp; if( S < M ) //當S<M,則做交換的動作 { temp = S; S = M; M =temp; } if(( S % M ) ==0) //x1和x2做遞迴的動作,求得最大公因數 return (M); else return (hcf ( M , S%M )); } public static void main(String[] args) { HCFLCM a=new HCFLCM(); System.out.println(a.hcf(70,168)); System.out.println(70*168/a.hcf(70,28)); } }
作業:1.遞迴方法完成1+2+…..+n 函數2.以遞迴方法完成費伯納函數F(n)=F(n-1)+F(n-2) F(1)=1 F(0)=1 1,1,2,3,5,8,13,213.遞迴方法完成m 加到n 函數(其中m<n,)m,n為整數