Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 תרגול 4 – פונקציות מבוא למדעי המחשב/מבוא לתכנות מערכות – סמסטר א' תשע"א.

Similar presentations


Presentation on theme: "1 תרגול 4 – פונקציות מבוא למדעי המחשב/מבוא לתכנות מערכות – סמסטר א' תשע"א."— Presentation transcript:

1 1 תרגול 4 – פונקציות מבוא למדעי המחשב/מבוא לתכנות מערכות – סמסטר א' תשע"א

2 2 היום בתרגול מה הן פונקציות הגדרת פונקציה, קריאה לפונקציה העברת ארגומנטים, החזרת ערך או void העברת משתנים פרימיטיביים ומערכים לפונקציה העמסה של פונקציות

3 3 מוטיבציה לעיתים, אנו נזקקים לבצע פעולה מסוימת או לעשות חישוב מסוים מס' רב של פעמים. במקום לשוב ולכתוב את הקוד מס' רב של פעמים, ניתן לכתוב פונקציה שעושה את הפעולה הרצויה ולקרוא לפונקציה זו בכל פעם שרוצים להשתמש בה. כבר ראינו את השימוש בפונקציה Math.abs()

4 4 מבנה של פונקציה public static (,, …) { } חתימה של פונקציה מורכבת משם הפונקציה ומרשימת טיפוסי הארגומנטים שהפונקציה מקבלת (מספר, סוגי טיפוסים וסדר) לכל שתי פונקציות בתכנית חתימה שונה הערך המוחזר וכן מאפיינים נוספים של פונקציה )כגון 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 )פעם אחת או יותר). ערך החזרה של פונקציה

6 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; System.out.println(max(dx1, max(dx2, dx3))); }

7 7 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; }

8 8 בזמן קריאה לפונקציה: השליטה של התכנית שומרת את המיקום הנוכחי שלה ועוברת לפונקציה. נפתחת סביבה (טבלת משתנים) חדשה שבה מוגדרים הפרמטרים של הפונקציה והמשתנים שמוגדרים בתוך הפונקציה. ההוראה return (או סיום הפונקציה במקרה של void) סוגרת את הסביבה ומחזירה את השליטה למקום בו היינו לפני הקריאה לפונקציה Flow of previous func

9 main sumNums(10) 9 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; } endint 10 sumint 0 lastIndint 10 sumint 55 sumint i 1 155

10 10 עוד קצת על פונקציות הפונקציה הראשית נקראת main וממנה מתחילה ההרצה. ניתן לכתוב פונקציות נוספות מלבד ה-main. הפונקציות יכולות לקרוא אחת לשניה. אפשר להעביר לפונקציה ערכים. פונקציה יכולה להחזיר ערך אחד בלבד או כלום. בכל פונקציה אפשר להגדיר משתנים הנקראים משתנים לוקליים,והם מוגדרים רק בתוך הפונקציה (SCOPE) Passing values/references iSum in the previous example

11 11 public static void printArray(int[] arr) { for(int i=0; i < arr.length; i=i+1) { System.out.print(arr[i]+” “); } System.out.println(); } הדפסת מערך של int-ים

12 חישוב המקדם הבינומי המציין את מספר תתי הקבוצות בגודל k, של קבוצה בגודל n. 12 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 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 העברת משתנים לפונקציה 14 ב-Java מועברים בעת קריאה לפונקציה בעלת פרמטרים, הערכים הרשומים בטבלת המשתנים, בין אם מדובר בערך ממש או בכתובת: - אם הפרמטר הוא מטיפוס פרימיטיבי, מה שיעבור לפונקציה הוא הערך של המשתנה, ולכן הפונקציה לא תוכל לשנות את המשתנה המקורי. - אם הפרמטר הוא מטיפוס שאינו פרימיטיבי, כלומר מכיל מצביע לאובייקט (כגון מערך), אז הפונקציה מקבלת את הכתובת, ויכולה לשנות את האובייקט בזיכרון.

15 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; System.out.println (x); }

16 16 אם היינו רוצים לשנות את הערך של xמה היינו עושים? היינו צריכים לשנות את add5כך שתחזיר ערך ואותו להכניס ל x : public static void main(String[] args){ int x=8; System.out.println(x); x=add5(x); System.out.println(x); } public static int add5(int x) { x = x+5; System.out.println(x); return x; }

17 17 public static void main(String[] arg){ int [] x={1,2,3}; printArray(x); add5(x); printArray(x); } public static void add5(int[] y) { for (int i=0 ; i<y.length ;i=i+1) y[i] = y[i]+5; printArray (y); } דוגמא להעברת פרמטרים מטיפוס לא פרימיטיבי: /* output 1 2 3 6 7 8 */ 123

18 18 הפונקציה הבאה אמורה להחליף ערכי שני משתנים מטיפוס int, ובכל זאת אינה עובדת. מה הבעיה? public static void swap(int a, int b){ int tmp; tmp = a; a = b; b = tmp; }

19 19 העמסה (Overloading) שתי פונקציות בעלות שם זהה (אבל חתימה שונה!). לדוגמא: Math.min(int,int) ו- Math.min(double,double) או System.out.println(int) ו- System.out.println(char) כמו כן, אופרטורים אריתמטיים הם דוגמאות נוספות להעמסה. -למשל, אופרטור החלוקה יכול לקבל שני ארגומנטים מסוג int או מסוג double. -איזה עוד דוגמאות לאופרטורים מועמסים ישנם? ‘+’ with strings

20 20 דוגמא להעמסה: public static int foo(int num){…} √ public static int foo(double num){…} √ public static double foo(int num){…}X אם היינו מחליפים את טיפוס הארגומנט בטיפוס int מה היה קורה? 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; else ans = i; return ans; }

21 21 /* output 2.0 2.0 2 2*/ 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)); // example for casting }

22 שאלות משנים קודמות

23 23 שאלה 4 מבוחן 2004 (17 נק') הפונקציה boolean allDiff(int[] a) מקבלת כקלט מערך של שלמים a ומחזירה "true" אם ורק אם כל אברי המערך שונים זה מזה. ניתן להניח כי מערך הקלט שונה מ- null. השלימו את גוף הפונקציה בדף התשובות. ניקוד מלא יינתן על סמך נכונות הקוד וסגנונו. public static boolean allDiff(int[] a){ boolean ans = true; // השלימו return ans; }

24 24 פתרון: 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;

25 25 שאלה 1 מבוחן 2002 (20 נקודות) מערך דו-ממדי נקרא מטריצה אם אינו ריק ואם כל שורותיו שוות באורכן ואורך זה גדול מאפס. השלימו את הגדרת השיטה הסטטית checkMatrix(int[][] m), אשר בודקת אם מערך דו-מימדי, m, היינו מטריצה ומחזירה ערך בוליאני בהתאם. הערה: אם קוראים לשיטה עם פרמטר שערכו null, על השיטה להחזיר את הערך false. בכל ריבוע ריק יש להשלים הוראה יחידה )כלומר לא יופיע בו (";". [דוגמא][דוגמא] &&

26 26 לשם הבהרה, השיטה :main תדפיס: true false 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)); }

27 27

28 28 שאלה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 -. יש להניח שבמערך יש לפחות שני מספרים שונים זה מזה. תוכלו גם להניח שכל המספרים הנתונים הם חיוביים, אך שימו לב שיתכן ואינם שונים זה מזה.

29 29 פתרון: 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; }

30 30 שאלה 6 מבוחן 2005(10 נקודות) להלן מספר משפטים. יש לסמן לכל סעיף "אמת" או "שקר". א. קיימים ערכים של 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!. ו. התשובות לעיל כולן שגויות. 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; } 531 435 335*4 325*4*3 225*4*3*3 215*4*3*3*2 115*4*3*3*2*2 105*4*3*3*2*2*1 005*4*3*3*2*2*1*1 abresult

31 31 פתרון:

32 32 שאלה 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)

33 33 פתרון: 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); }


Download ppt "1 תרגול 4 – פונקציות מבוא למדעי המחשב/מבוא לתכנות מערכות – סמסטר א' תשע"א."

Similar presentations


Ads by Google