Download presentation
Presentation is loading. Please wait.
1
מבוא למדעי המחשב תרגול 4 – פונקציות
2
היום בתרגול מה הן פונקציות הגדרת פונקציה, קריאה לפונקציה
העברת ארגומנטים, החזרת ערך או void העברת משתנים פרימיטיביים ומערכים לפונקציה העמסה של פונקציות
3
מוטיבציה לעיתים, אנו נזקקים לבצע פעולה מסוימת או לעשות חישוב מסוים מס' רב של פעמים. במקום לשוב ולכתוב את הקוד מס' רב של פעמים, ניתן לכתוב פונקציה שעושה את הפעולה הרצויה ולקרוא לפונקציה זו בכל פעם שרוצים להשתמש בה. כבר ראינו את השימוש בפונקציה Math.abs()
4
מבנה של פונקציה public static <return type> <func name> (<arg1_type> <arg1>, <arg2_type> <arg2>, …) { <function body> } חתימה של פונקציה מורכבת משם הפונקציה ומרשימת טיפוסי הארגומנטים שהפונקציה מקבלת (מספר, סוגי טיפוסים וסדר). הערך המוחזר וכן מאפיינים נוספים של פונקציה )כגון public ו- static ) אינם נכללים בחתימה של הפונקציה. לכל שתי פונקציות בתכנית חתימה שונה public static int foo(int num){…} public static int foo(int num1, double num2){…} public static int foo(double num){…} public static double foo(int num){…} √ X
5
ערך החזרה של פונקציה יש פונקציות שלא צריכות להחזיר ערך, אלא רק לבצע משהו (למשל פונקציה שמדפיסה מערך). במצב כזה נכתוב מילה void בתור <return value type>. פונקציה שמחזירה ערך חייבת להכיל את הפקודה <value>” “return )פעם אחת או יותר).
6
דוגמאות להגדרה ושימוש בפונקציות:
// Shows how to define and use a simple function public class Max { // returns the larger number between the arguments public static double max(double dx, double dy) { double ans; if(dx < dy) ans = dy; else ans = dx; return ans; } public static void main(String[] args) { double dx1, dx2, dx3; dx1 = 2; dx2 = 0; dx3 = -1.8; double tmp = max(dx2, dx3); System.out.println(max(dx1, tmp));
7
דוגמאות להגדרה ושימוש בפונקציות:
// Shows how to define and use a simple function public class Max { // returns the larger number between the arguments public static double max(double dx, double dy) { double ans; if(dx < dy) ans = dy; else ans = dx; return ans; } public static void main(String[] args) { double dx1, dx2, dx3; dx1 = 2; dx2 = 0; dx3 = -1.8; System.out.println(max(dx1, max(dx2, dx3))); 7
8
בזמן קריאה לפונקציה: השליטה של התכנית שומרת את המיקום הנוכחי שלה ועוברת לפונקציה. נפתחת סביבה (טבלת משתנים) חדשה שבה מוגדרים הפרמטרים של הפונקציה והמשתנים שמוגדרים בתוך הפונקציה. ההוראה return (או סיום הפונקציה במקרה של void) סוגרת את הסביבה ומחזירה את השליטה למקום בו היינו לפני הקריאה לפונקציה
9
end int sum int lastInd int i int 1 sum int sum int
public class Sum { public static void main(String[] args) { int lastInd = 10; int sum = sumNums(lastInd ); System.out.println(“The sum of numbers from 1 to “+ lastInd + “ = “ + sum); System.out.println(“The sum of numbers from 1 to “+ 8 + “ = “ + sumNums(8)); } // returns the sum of numbers from 1 to end public static int sumNums(int end) { int sum = 0; for(int i = 1; i <= end; i = i+1) sum = sum + i; return sum; sumNums(10) end int 10 main sum int 1 55 lastInd int 10 i int 1 sum int 55 sum int
10
עוד קצת על פונקציות הפונקציה הראשית נקראת main וממנה מתחילה ההרצה. ניתן לכתוב פונקציות נוספות מלבד ה-main. הפונקציות יכולות לקרוא אחת לשניה. אפשר להעביר לפונקציה ערכים. פונקציה יכולה להחזיר ערך אחד בלבד או כלום. בכל פונקציה אפשר להגדיר משתנים הנקראים משתנים לוקליים ,והם מוגדרים רק בתוך הפונקציה (SCOPE)
11
הדפסת מערך של int-ים public static void printArray(int[] arr) {
for(int i=0; i < arr.length; i=i+1) { System.out.print(arr[i]+” ”); } System.out.println();
12
חישוב המקדם הבינומי המציין את מספר תתי הקבוצות בגודל k , של קבוצה בגודל n.
public class BinCoeff { public static void main(String[] args) { int n = 5 , k = 3; System.out.print("The number of different subsets of size " + k + " in a set of size " + n + " is: "); System.out.println(nChooseK(n,k)) ; } … /* output : The number of different subsets of size 3 in a set of size 5 is: 10 */
13
// Assumes that n>=0 public static int factorial(int n) { int result = 1; for(int i=2; i <= n; i = i+1) { result = result * i; } return result; public static int nChooseK(int n, int k) { int ans = 0; if (n>=k && k>=0) { ans = factorial(n) / (factorial(k) * factorial(n-k)); return ans;
14
העברת משתנים לפונקציה ב-Java מועברים בעת קריאה לפונקציה בעלת פרמטרים, הערכים הרשומים בטבלת המשתנים, בין אם מדובר בערך ממש או בכתובת: - אם הפרמטר הוא מטיפוס פרימיטיבי, מה שיעבור לפונקציה הוא הערך של המשתנה , ולכן הפונקציה לא תוכל לשנות את המשתנה המקורי. - אם הפרמטר הוא מטיפוס שאינו פרימיטיבי, כלומר מכיל מצביע לאובייקט (כגון מערך), אז הפונקציה מקבלת את הכתובת, ויכולה לשנות את האובייקט בזיכרון.
15
דוגמא להעברת פרמטרים מטיפוס פרימיטיבי:
public static void main(String[] args){ int x=8; System.out.println(x); add5(x); System.out.println (x); } public static void add5(int x){ x = x+5;
16
אם היינו רוצים לשנות את הערך של x מה היינו עושים?
היינו צריכים לשנות את add5 כך שתחזיר ערך ואותו להכניס ל x : public static void main(String[] args) { int x=8; System.out.println(x); x=add5(x); } public static int add5(int x) { x = x+5; return x; 16
17
דוגמא להעברת פרמטרים מטיפוס לא פרימיטיבי:
public static void main(String[] arg) { int [] x={1,2,3}; printArray(x); add5(x); } public static void add5(int[] y) { for (int i=0 ; i<y.length ;i=i+1) y[i] = y[i]+5; printArray (y); 1 2 3 /* output 1 2 3 6 7 8 */ 17
18
הפונקציה הבאה אמורה להחליף ערכי שני משתנים מטיפוס int, ובכל זאת אינה עובדת. מה הבעיה?
public static void swap(int a, int b) { int tmp; tmp = a; a = b; b = tmp; } 18
19
שתי פונקציות בעלות שם זהה (אבל חתימה שונה!). לדוגמא:
העמסה (Overloading) שתי פונקציות בעלות שם זהה (אבל חתימה שונה!). לדוגמא: Math.min(int,int) ו- Math.min(double,double) או System.out.println(int) ו- System.out.println(char) כמו כן, אופרטורים אריתמטיים הם דוגמאות נוספות להעמסה. למשל, אופרטור החלוקה יכול לקבל שני ארגומנטים מסוג int או מסוג double. איזה עוד דוגמאות לאופרטורים מועמסים ישנם? 19
20
דוגמא להעמסה: public class Max {
// returns the larger between the arguments public static double max(double d1, double d2) { double ans; if(d1 < d2) ans = d2; else ans = d1; return ans; } public static int max(int i, double d) { int ans; if(i < d) ans = (int)d; ans = i; אם היינו מחליפים את טיפוס הארגומנט בטיפוס int מה היה קורה? public static int foo(int num){…} √ public static int foo(double num){…} √ public static double foo(int num){…} X 20
21
public static void main(String[] args) { int i1 = 1, i2 = 2 ;
public static double max(double d1, double d2) { … } public static int max(int i, double d) { … } public static void main(String[] args) { int i1 = 1, i2 = 2 ; double d1 = 2, d2 = 0 ; System.out.println(max(d1,d2)); System.out.println(max(i1,d1)); System.out.println(max(i1,i2)); } 2.0 2 2 נבחר את הפונקציה עם המינימום המרות. static double max(double d1, double d2) – שתי המרות static int max(int i, double d) – המרה אחת 21
22
שאלות משנים קודמות
23
שאלה 4 מבוחן 2004 (17 נק') הפונקציה boolean allDiff(int[] a) מקבלת כקלט מערך של שלמים a ומחזירה "true" אם ורק אם כל אברי המערך שונים זה מזה. ניתן להניח כי מערך הקלט שונה מ- null. השלימו את גוף הפונקציה בדף התשובות. ניקוד מלא יינתן על סמך נכונות הקוד וסגנונו. public static boolean allDiff(int[] a) { boolean ans = true; // השלימו return ans; } 23
24
פתרון: public static boolean allDiff(int[] a) { boolean ans = true;
for(int i = 0; i < a.length-1 && ans; i=i+1) { for(int j = i+1; j < a.length && ans; j=j+1) { if(a[i] == a[j]) { ans = false; } return ans; } 24
25
שאלה 1 מבוחן 2002 (20 נקודות) מערך דו-ממדי נקרא מטריצה אם אינו ריק ואם כל שורותיו שוות באורכן ואורך זה גדול מאפס. השלימו את הגדרת השיטה הסטטית checkMatrix(int[][] m), אשר בודקת אם מערך דו-מימדי, m, היינו מטריצה ומחזירה ערך בוליאני בהתאם. הערה: אם קוראים לשיטה עם פרמטר שערכו null, על השיטה להחזיר את הערך false. בכל ריבוע ריק יש להשלים הוראה יחידה )כלומר לא יופיע בו (";". [דוגמא] && 25
26
תדפיס: true false לשם הבהרה, השיטה :main
public static void main (String[] args){ int[] line1 = {1,2,3,4}; int[] line2 = {5,6,7,8}; int[] line3 = {9}; int[] line4 = new int[0]; int[][] m1 = {line1,line2}; int[][] m2 = {line1,line2,line3}; int[][] m3 = null; int[][] m4 = {null,null}; int[][] m5 = {line4,line4}; int[][] m6 = {line2,null}; int[][] m7 = new int[0][0]; System.out.println(checkMatrix(m1)); System.out.println(checkMatrix(m2)); System.out.println(checkMatrix(m3)); System.out.println(checkMatrix(m4)); System.out.println(checkMatrix(m5)); System.out.println(checkMatrix(m6)); System.out.println(checkMatrix(m7)); } תדפיס: true false
27
(m[i]!=null && m[0].length==m[i].length)
שאלה 1 מבוחן 2002 (20 נקודות) (m!=null && m.length>0 && m[0]!=null && m[0].length>0); tmp && i<m.length && (m[i]!=null && m[0].length==m[i].length) 27
28
שאלה 6 מבוחן 2005(10 נקודות) a b result 5 3 1 4 3 5 3 5*4 3 2 5*4*3 2
שאלה 6 מבוחן (10 נקודות) a b result public static int mystery(int a, int b){ int result = 1; while(a!=0 || b!=0){ if(a > b){ result = result * a; a = a - 1; } else { result = result * b; b = b - 1; } return result; 5 3 1 4 3 5 3 5*4 3 2 5*4*3 2 5*4*3*3 2 1 5*4*3*3*2 1 5*4*3*3*2*2 1 5*4*3*3*2*2*1 5*4*3*3*2*2*1*1 להלן מספר משפטים. יש לסמן לכל סעיף "אמת" או "שקר". א. קיימים ערכים של a ו-b הגורמים ללולאה אינסופית. (ענו שקר או במקרה שתשובתכם אמת תנו דוגמא לערכים של a ו- b כאלו). ב. קיימים ערכים של a ו-b עבורם התוכנית תדפיס בסוף: " The result: 0". (ענו שקר או במקרה שתשובתכם אמת תנו דוגמא לערכים של a ו- b כאלו). ג. לכל a>b>0 ערך של ה-result בסוף התכנית יהיה שווה ל-a. ד. לכל a>b>0 ערך של ה-result בסוף התכנית יהיה שווה ל .a! x b! ה. לכל a>b>0 ערך של ה-result בסוף התכנית יהיה שווה ל-a!. ו. התשובות לעיל כולן שגויות. 29
29
פתרון:
30
שאלה 5מבוחן 17 ) 2004נקודות) נתונה הפונקציה public static int oddGCD(int m, int n) לחישוב המחלק המשותף המקסימלי (gcd) של שני מספרים שלמים m ו- n .שיטה זו פועלת נכון רק במקרה ולפחות אחד המספרים הינו אי-זוגי. השלימו את הגדרת השיטה הבאה, תוך שימוש בשיטה oddGCD הנתונה, כך שתחשב את המחלק המשותף המקסימאלי עבור כל שני שלמים אי-שליליים (הניחו כי לפחות אחד המספרים אינו אפס.( בפתרון שתציעו אין לבצע כל בדיקה על ערכו של משתנה פרט לבדיקה האם הוא זוגי או לא. כמובן שניתן גם להשתמש בפעולות לוגיות כמו (!, &&, ||). ניתן להניח שהקלט הינו חוקי (כלומר ש- n ו- m אי-שליליים ולפחות אחד מהם חיובי ממש). public static int generalGCD(int m, int n) { // השלימו } רמז: gcd(x∙y, x∙z) = x∙gcd(y,z) 31
31
פתרון: public static int generalGCD(int m, int n) { int multiply = 1;
while( (m % 2 == 0) && (n % 2 == 0) { multiply = multiply * 2; m = m / 2; n = n / 2; } return multiply * oddGCD(m, n);
32
שאלה2 מבוחן 2002(20 נק') נאמר ששני מספרים טבעיים חיוביים הם זרים אם אין להם מחלק משותף (פרט ל- 1). נתונה לכם שיטה סטטית public static int gcd (int m, int n) אשר מחזירה את המחלק המשותף הגדול ביותר של שני מספרים טבעיים חיוביים. השלימו את השיטה checkGCD(int[] a) אשר מחזירה ערך בוליאני המציין האם מערך a מקיים אחת משתי התכונות הבאות: א. כל שני מספרים שונים ב- a זרים. ב. כל שני מספרים שונים ב-a אינם זרים. למשל: האוסף 4,7,25 מקיים את תכונה א' האוסף 6,10,15 מקיים את תכונה ב', למרות שאין שום מספר גדול מ- 1 המחלק את שלושת המספרים. האוסף20,7,20 מקיים את תכונה א' כי רק 7 ו- 20 שונים והם זרים. האוסף4,7,28 אינו מקיים אף אחת משתי התכונות. הפעלתcheckGCD על שלושת המערכים הראשונים מחזירה true. ואילו על הרביעי false -. יש להניח שבמערך יש לפחות שני מספרים שונים זה מזה. תוכלו גם להניח שכל המספרים הנתונים הם חיוביים, אך שימו לב שיתכן ואינם שונים זה מזה. 33
33
פתרון: public static boolean checkGCD(int[] a){
boolean aliens = true; // each 2 are aliens boolean notAliens = true; // each 2 are not aliens for (int i = 0; i < a.length – 1 && (aliens || notAliens); i=i+1){ for (int j = i+1; j < a.length && (aliens || notAliens); j=j+1){ if (a[i] != a[j]) { if (gcd(a[i], a[j]) == 1) notAliens = false; else aliens = false; } return aliens || notAliens;
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.