1 / 82

פונקציות

פונקציות. קרן כליף. ביחידה זו נלמד:. מהי פונקציה, פרמטרים וערך מוחזר כיצד נראה הזיכרון ספריות של פונקציות מערכים כפרמטר לפונקציה יצירת מספרים אקראיים פונקציות מ- math.h תהליך הפיכת תוכנית ב- ++ C לשפת מכונה סוגי משתנים וטווח הכרתם: לוקאליים, גלובליים, סטטיים. מהי פונקציה.

Télécharger la présentation

פונקציות

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. פונקציות קרן כליף

  2. ביחידה זו נלמד: מהי פונקציה, פרמטרים וערך מוחזר כיצד נראה הזיכרון ספריות של פונקציות מערכים כפרמטר לפונקציה יצירת מספרים אקראיים פונקציות מ- math.h תהליך הפיכת תוכנית ב- ++C לשפת מכונה סוגי משתנים וטווח הכרתם: לוקאליים, גלובליים, סטטיים

  3. מהי פונקציה • פונקציה היא אוסף הוראות לביצוע שמממשות רעיון משותף • למשל sizeof היא פונקציה • גם ה- main שאנחנו כותבים הוא פונקציה • עבורנו פונקציות אלו הן "קופסא שחורה" שקיבלנו מספריה מסוימת, ואנו רק יודעים מה הן עושות, אבל לא יודעים איך, כלומר מהו אוסף הפעולות המבוצעות בשיעור זה נלמד לכתוב פונקציות בעצמנו!

  4. דוגמא לשימוש בפונקציה #include <iostream> using namespace std; void main() { int num, size; size = sizeof(num); cout << "the variable 'num' uses “ << size << “ bytes\n”; } הערך המוחזר מהפונקציה שם הפונקציה הנתונים המועברים. כל נתון נקרא ארגומנט

  5. דוגמא לשכפול קוד: חישוב חלוקת log const int BASIS =10; void main() { int num1=100, num2=1000, res; int log1, log2; res = BASIS; for (log1=1 ; res < num1 ; log1++) res *= BASIS; cout << "log(" << num1 << ") = " << log1 << endl; res = BASIS; for (log2=1 ; res < num2 ; log2++) res *= BASIS; cout << "log(" << num2 << ") = " << log2 << endl; cout << "log(" << num1 << "/" << num2 << ") = " << log1-log2 << endl; { רצף הפעולות לחישוב לוג זהה, רק כל פעם ביצענו את הפעולות על ערכים שונים  שכפול קוד! מי שקורא את ה- main צריך להבין מה תפקידה של כל לולאה... חישוב log10100 חישוב 0log10100

  6. הדוגמא ללא שכפול קוד, קריאות טובה ומודלריות שם הפונקציה. יעיד מה היא עושה #include <iostream> using namespace std; const int BASIS=10; int log(int num) } int res = BASIS, i; for (i=1 ; res < num ; i++) res *= BASIS; return i; { void main() } int num1=100, num2=1000, res; res = log(num1) - log(num2); cout << "log(“ << num1 << “/” << num2 << “) = “ << res << endl; { טיפוס המידע שהפונקציה מחזירה הנתון שהפונקציה צריכה לקבל עם השימוש בפונקציה הקוד קצר יותר וקריא יותר! ה- main כתוב ב"ראשי פרקים" וניתן להבין בקלות מה הוא מבצע איך הפונקציה מבצעת את העבודה הערך שהפונקציה מחזירה שימוש בערך שהפונקציה מחזירה קריאה לפונקציה שיודעת לחשב log, פעם עם num1 ופעם עם num2

  7. פונקציות - מוטיבציה • מודולריות: חלוקת התוכנית לקטעי קוד יותר קטנים, כאשר כל קטע עושה משהו נקודתי • יתרונות: • קוד קריא יותר • יותר קל לבדוק את התוכנית • חלוקת עבודה • שימוש חוזר בקוד • חיסכון בבדיקות • פחות שגיאות

  8. תזכרו! http://www.thedistractionnetwork.com/images/programming-fail-007.jpg

  9. החלקים בשילוב פונקציה שלנו בקוד • הצהרה על הפונקציה • כאשר כותבים פונקציה ראשית צריך להחליט מה הפונקציה עושה • לאחר שהחלטנו על ה"מה", יש להחליט אילו נתונים הפונקציה צריכה לקבל כדי לבצע את העבודה • לבסוף נגדיר מה הטיפוס שהפונקציה מחזירה לנו • שימוש בפונקציה • מימוש הפונקציה

  10. איך כותבים הצהרה של פונקציה • דוגמא: פונקציה המחשבת חזקה • מה הפונקציה עושה: הפונקציה מחשבת חזקה של שני מספרים • מה הפונקציה מקבלת: 2 מספרים, הראשון בסיס והשני מעריך • מה הפונקציה מחזירה: את תוצאת חישוב הבסיס במעריך • לבחור שם משמעותי לפונקציה int base int exponent • תחביר: int power(int base, int exponent) • ובאופן כללי: int baseexponent (<parameters list>) <returned value type> <function_name>

  11. בחירת שם לפונקציה • שם הפונקציה צריך להעיד מה היא עושה • למשל: power, printf • מבחינת סגנון כתיבה, ההמלצה היא: • שם הפונקציה יתחיל באות קטנה • אם יש יותר ממילה אחת בשם הפונקציה כל מילה נוספת תתחיל באות גדולה • למשל: calcRectangleArea • ניתן לאמץ סגנון אחר, אבל הקפידו להיות עקביים בסגנון לאורך כל התוכנית. כנ"ל גם לגבי שמות משתנים

  12. הצהרת פונקציה - הערך המוחזר (1) • הערך המוחזר יכול להיות כל אחד מהטיפוסים שאנחנו מכירים • למשל, פונקציה המקבלת אורך צלע ריבוע ומחזירה את שטחו int calcSquareArea(int length); • למשל, פונקציה המקבלת מספר, ומחזירה את השורש שלו double sqrt(int num);

  13. הצהרת פונקציה - הערך המוחזר void • אם הפונקציה אינה מחזירה ערך, נרשום כערך המוחזר void • החזרה = ניתן לאכסן ערך במשתנה כלשהו • שימו לב: הדפסה למסך אינה החזרה של ערך! • למשל, פונקציה המדפיסה למסך void printRectangle(int base)

  14. הצהרת פונקציה – הפרמטרים המועברים • רשימת הנתונים אשר הפונקציה מקבלת מופרדת ע"י פסיקים • דוגמא: פונקציה המקבלת אורך ורוחב של מלבן ומחזירה את שטחו int calcRectangleArea(int height, int width); • למשל, פונקציה המקבלת מספר n ומחזירה n! int factorial(int num); • אם פונקציה אינה מקבלת נתונים, רשימת הפרמטרים תהייה ריקה • למשל, פונקציה הקוראת מהמשתמש את גילו ומחזירה אותו int readAge();

  15. מימוש פונקציה • דוגמא למימוש פונקציה המקבלת בסיס ומעריך ,ומחזירה את החזקה int power(int a, int b) { int result=1; for (int i=0 ; i < b ; i++) result *= a; return result; } הפקודה return מציינת הפסקת ביצוע הפקודות בפונקציה והחזרת ערך המשתנה פונקציה שהערך המוחזר שלה הוא void אינה חייבת להכיל את הפקודה return. באם מופיעה הפקודה return בפונקציה המחזירה void, רצף הפעולות יפסק מיד.

  16. אבל זהירות! http://funnypictures4u.files.wordpress.com/2013/06/people_vs_programmers.jpg

  17. תוכנית שלמה עם פונקציה int a int b int power(, ) { int i, result=1; for (i=0 ; i < b ; i++) result *= a; return result; } void main() { int base, exponent, result; cout << "Please enter base and exponent: “; cin >> base >> exponent; = power(,); cout << base << “^” << exponent << “=“ << result << endl; } הפונקציה מוכרת ממקום הגדרתה ומטה, הצהרת הפונקציה תופיע לפני השימוש!ולכן הצהרה+מימוש יש להעביר לפונקציה משתנים כמספר הפרמטרים שהיא דורשת, מאותו הסוג ובאותו הסדר! נשים לב כי בקריאה לפונקציה מעבירים רק את שמות המשתנים, ולא את הטיפוסים, בניגוד להצהרת ומימוש הפונקציה! איחסון הערך המוחזר מהפונקציה שימוש base exponent result

  18. דוגמא: תוכנית שלמה עם הפונקציה max int max (int x, int y) { if (x > y) return x; else return y; } void main() { int num1, num2, maximum; cout << "Enter 2 numbers: "; cin >> num1 >> num2; max(num1, num2); cout << "The max is “ << maximum << endl; } בשורה זו מוערך הביטוי מימין וערכו נכנס לתוך המשתנה maximum. לא חייבים לאחסן את הערך המוחזר! maximum =

  19. ואפשר גם כך.. int max (int x, int y) { if (x > y) return x; return y;// witout the ‘else’… } void main() { int num1, num2, maximum; cout << "Enter 2 numbers: “; cin >> num1 >> num2; maximum = max(num1, num2); cout << "The max is “ << maximum << endl; }

  20. מחסנית הקריאות • כאשר קוראים לפונקציה, למעשה "קופצים" לאוסף הפקודות שלה, ושומרים את מקום החזרה • כאשר נתקלים בפקודה return בתוך גוף הפונקציה, חוזרים לביצוע הפעולות מהמקום בו קראנו לה • בפונקציה שהטיפוס המוחזר שלה הוא void יתכן ולא תהייה הפקודה return • במקרה זה, לאחר סיום הפונקציה, חוזרים לביצוע הפעולות מהמקום בו קראנו לפונקציה

  21. תוכנית שלמה עם פונקציה - הרצה #include <iostream> using namespace std; int power(int a, int b) { int i, result=1; for (i=0 ; i < b ; i++) result *= a; return result; } void main() { int base, exponent, result; cout << "Please enter base and exponent: “; cin >> base >> exponent; = power(base, exponent); cout << base << “^” << exponent << “=“ << result << endl; } power main ( line 4) מחסנית הקריאות result

  22. סדר ביצוע פעולות #include <iostream> using namespace std; int power(int a, int b) { cout << "debuging.. in 'power'\n”; int i, result=1; for (i=0 ; i < b ; i++) result *= a; return result; } void main() { cout << "2^3=“ << power(2, 3) << endl; } קודם תבוצע הפונקציה

  23. סדר ביצוע פעולות (2) #include <iostream> using namespace std; int power(int a, int b) { cout << "debuging.. in 'power': a=“ << a << “ b=“ << b < endl; int i, result=1; for (i=0 ; i < b ; i++) result *= a; return result; } void main() { cout << "2^4=" << power(2, 4) << " 2^5=" << power(2, 5) << endl; } ביצוע הפונקציות מתבצע מימין לשמאל

  24. כיצד נראה הזיכרון • ראינו את הזיכרון של ה- main • תזכורת: ה- main הוא פונקציה • לכל פונקציה יש שטח נפרד בזיכרון ה- stack בו מוגדרים משתניה • פונקציה יכולה לגשת לשטח הזיכרון שלה בלבד, ולכן אינה יכולה לגשת למשתנים שהוגדרו בפונקציות אחרות • הפרמטרים המועברים לפונקציה הם גם משתנים של הפונקציה • הפרמטרים המועברים לפונקציה הם העתקים של המשתנים שנשלחו, ולכן העברת פרמטרים כזו נקראת by value • כאשר יוצאים מפונקציה, התאים במחסנית שבהם נשמרו ערכיה נמחקים, ולכן קריאה נוספת לפונקציה תייצר אותם מחדש

  25. תוכנית שלמה עם פונקציה - הזיכרון #include <iostream> using namespace std; int power(int a, int b) { int i, result=1; for (i=0 ; i < b ; i++) result *= a; return result; } void main() { int base, exponent, result; cout << "Please enter base and exponent: “; cin >> base >> exponent; = power(base, exponent); cout << base << “^” << exponent << “=“ << result << endl; } הזיכרון של ה- main המשתנה result שב-main וזה שבפונקציה אינם אותו משתנה, ואין הכרח שהם יהיו עם שם זהה! הזיכרון של power power main ( line 4) מחסנית הקריאות result

  26. הפרדה בין הצהרות למימוש #include <iostream> using namespace std; // prototypes void main() { int base, exponent, result; cout << "Please enter base and exponent: “; cin >> base >> exponent; result = power(base, exponent); cout << base << “^” << exponent << “=“ << result << endl; } int power(int base, int exponent) { int i, result=1; for (i=0 ; i < exponent ; i++) result *= base; return result; } בשורת ההצהרה לא חייבים לציין את שמות המשתנים int power(int, int); int power(int base, int exponent); • את ההצהרות נרשום לפני ה- main, ובסיום כל הצהרה ; • חלק זה נקרא prototype (אב-טיפוס) • את המימושים נכתוב מתחת ל- main • ההפרדה היא מאחר ומעניין אותנו איזה פונקציות יש בתוכנית, ופחות איך הן מבצעות את העבודה • חתימת הפונקציה בהגדרה בראש הקובץ ובמימוש חייבות להיות זהות

  27. תכנון TOP-DOWN • כאשר ניגשים לכתוב תוכנית, יש לחשוב מהי הבעיה הגדולה שעלינו לפתור ונחלק אותה לחלקים • לכל חלק "קשה" נתייחס כאל "קופסא שחורה" (שתמומש בהמשך) • כאשר נממש כל חלק "קשה" אנו מתמודדים עם בעיה יותר קטנה שננסה גם אותה לפרק לבעיות יותר קטנות, עד אשר נגדיר בעיות מספיק קטנות

  28. תכנות TOP-DOWNדוגמא: ציור משולש #include <iostream> using namespace std; // prototypes void printLine(int, char); void printTriangle(int, char); void main() { int base; char ch; cout << "Enter base and char: “; cin >> base >> ch; printTriangle(base, ch); } void printLine(int length, char c) { inti; for ( ; ; ) cout << c; cout << endl; } void printTriangle(int base, char ch) { inti; for( ; ; ) printLine(i, ch); } i=1 i<=length i++ הזיכרון של printLine print Line i=1 i<=base i++ print Triangle (line 3) main ( line 5) מחסנית הקריאות הזיכרון של ה- main הזיכרון של printTriangle

  29. דוגמאת סיכום: חישוב מרחק בין 2 נקודות • הנוסחא לחישוב מרחק בין 2 הנקודות (x1,y1) ו- (x2,y2): • נרצה לכתוב פונקציה המקבלת 4 קואורדינטות המייצגות 2 נקודות, ומחזירה את המרחק בניהן: int x1 int y1 int x2 int y2 • לכן ההצהרה של הפונקציה תראה כך: float distance(int x1, int y1, int x2, int y2); distance float dist

  30. דוגמא: חישוב מרחק בין 2 נקודות (2) • הנוסחא לחישוב מרחק בין 2 הנקודות (x1,y1) ו- (x2,y2): • ניתן לראות שכדי לחשב מרחק בין שתי נקודות צריך לדעת לחשב חזקה ושורש, לכן נגדיר ונשתמש ב- 2 פונקציות עזר: • sqrt המקבלת מספר float ומחזירה את השורש שלו. פונקציה זו כבר קיימת בספריה math.h • power שאותה נכתוב בעצמנו לצורך התרגול (למרות שהיא גם קיימת ב- math.h)

  31. float distance(int x1, int y1, int x2, int y2) { float xDiffPower, yDiffPower; float result; power(x2-x1, 2); power(y2-y1, 2); sqrt(xDiffPower+yDiffPower); return result; } #include <iostream> using namespace std; #include <math.h> int power(int base, int exponent); float distance(int x1, int y1, int x2, int y2); void main() { int x1, y1, x2, y2; float dist; cout << "Please enter 2 points (x1, y1, x2, y2): “; cin >> x1 >> y1 >> x2 >> y2; distance(x1, y1, x2, y2); cout << "The distance is “ << dist << endl; } int power(int base, int exponent) { int i, result=1; for (i=0 ; i < exponent ; i++) result *= base; return result; } include לספריה שנשתמש בפונקציה ממנה הצהרות על פונקציות שנממש xDiffPower = yDiffPower = result = גם ל- power יש מרחב זיכרון, אך לא נראה אותו פה מפאת חוסר מקום ;+) מימוש הפונקציות שלנו dist = קריאה לפונקציות הזיכרון של ה- main power sqrt distance (line 3) distance (line 4) distance (line 5) main ( line 5) מחסנית הקריאות הזיכרון של distance

  32. פונקציות ספריה • כל תוכנית בשפת תכנות עילית, ובפרט שפת ++C, מורכבת מאוסף של פונקציות • קיימות פונקציות ספריה בשפה אותן ניתן להכליל בתוכנית ולקרוא להן בכל מקום בו נרצה ולהשתמש בהן כמה פעמים שנרצה • למשל כאשר עושים: #include <iostream> ניתן להשתמש בפונקציות המוגדרות בספריה זו בכל מיני מקומות בקוד (למשל cin, cout) • גם אנו יכולים לכתוב פונקציות או ספריות של פונקציות, שאותן ניתן להכליל ולהשתמש בהן כרצוננו

  33. יצירת קובץ ספריה • עד כה השתמשנו בפונקציות שקיבלנו משפת C • כל פונקציה כזו נכתבה בספריה שאליה ביצענו include • למשל כדי להשתמש בפונקציות של מחרוזות, עשינו #include <string.h> • כדי לייצר ספריה משלנו נייצר 2 קבצים חדשים: • <file_name>.hהוא קובץ אשר יכלול את ה- prototypes של הפונקציות, ואליו אח"כ נעשה include מהקובץ שירצה להשתמש בפונקציות המוגדרות בו • <file_name>.cppהוא קובץ שיכיל include לקובץ ה- header התואם ויממש את הפונקציות המוגדרות בו • include לספריה שכתבנו יהיו בתוך ""(גרשיים) ולא בתוך <>

  34. דוגמא – ספריה המטפלת בתווים (1) הקובץ character.h // prototypes int isSmallLetter(char); int isCapitalLetter(char); int isAlpha(char); int isDigit(char);

  35. דוגמא – ספריה המטפלת בתווים (2) #include "charachter.h" int isSmallLetter(char ch) { return (ch >= 'a' && ch <= 'z'); } int isCapitalLetter(char ch) { return (ch >= 'A' && ch <= 'Z'); } int isAlpha(char ch) { return (isSmallLetter(ch) || isCapitalLetter(ch)); } int isDigit(char ch) { return (ch >= '0' && ch <= '9'); } הקובץ character.cpp

  36. דוגמא – ספריה המטפלת בתווים (3) #include <iostream> using namespace std; #include "charachter.h" void main() { char ch=0; printf("Please enter a charachter: "); ch = getchar(); printf("Is '%c' a digit? %d\n", ch, isDigit(ch)); printf("Is '%c' a small letter? %d\n", ch, isSmallLetter(ch)); printf("Is '%c' a capital letter? %d\n", ch, isCapitalLetter(ch)); printf("Is '%c' a letter? %d\n", ch, isAlpha(ch)); } הקובץ main.cpp

  37. ספריות שלנו - סיכום • ניתן לכתוב את כל הקוד בקובץ אחד, אבל אם אנחנו כותבים קוד כללי, שיתכן ויהיה שימושי גם במקומות אחרים, נעדיף לחלק את הקוד לקובץ ספריה נפרד • מי שירצה להשתמש בספריה שלנו, יתעניין מה יש לה להציע, ולא איך היא מבצעת את הפעולות, וכך הוא יוכל להסתכל בקובץ header בלבד בו יש ריכוז של כל הפונקציות • מכירת הספריה ללקוח תסתכם בקובץ ה- h ובקובץ בינארי שהוא תוצר של הקומפילציה, וכך לא נחשוף את ה"איך"

  38. דוגמא איך לא כותבים פונקציה #include <iostream> using namespace std; void power() { int base, exponent, i, result=1; cout << "Please enter base and exponent: "; cin >> base >> exponent; for (i=0 ; i < exponent ; i++) result *= base; cout << "The result is “ << result << endl; } void main() { power(); }

  39. מדוע לא לכתוב קוד כמו הדוגמא הקודמת? • ניתן לעקוף חלקית את הרעיון של העברת ארגומנטים והחזרת ערך מפונקציות ע"י כך שפונקציה תבקש מהמשתמש את הנתונים ותדפיס בסוף את התוצאה • למשל, כמו בדוגמא הקודמת, הפונקציה המחשבת חזקה לא קיבלה פרמטרים ולא החזירה את התוצאה • לא נעשה זאת! • נמנע מלקלוט קלט בתוך פונקציה, אלא אם זה יעוד הפונקציה • הסיבה: יתכן ופונקציה אחרת צריכה להשתמש בנתון המתקבל או להעביר נתון, ולא ניתן לצפות מי ישתמש בפונקציה שלנו • דוגמא: כמו בפונקציהdistance הקוראת ל- power • כדי לבדוק פונקציה, נקלוט את הנתונים ב- main ונעבירם לפונקציה. את התוצאה נדפיס ב- main.

  40. העברת פרמטר לפונקציה – by reference • ראינו: • כאשר מעבירים משתנה לפונקציה עותק שלו מועבר למחסנית של הפונקציה (העברה by value) • אם בפונקציה משנים את הפרמטר זה לא משפיע על המשתנה המקורי • מה יקרה כאשר נרצה שהפונקציה תשנה דווקא את הפרמטרים שקיבלה? • נעביר הפניה למשתנה המקורי...

  41. שליחת פרמטר by refלעומת by val void changeTo4byVal(int x) { x = 4; { void changeTo4byRef(int& x) } x = 4; } void main() } int num = 10; cout << "orig num = " << num << endl; changeTo4byVal(num); cout << "after changeTo4byVal: num = " << num << endl; changeTo4byRef(num); cout << "after changeTo4byRef: num = " << num << endl; { הזכרון של ה- chagneTo4ByVal הזכרון של ה- chagneTo4ByRef הזכרון של ה- main

  42. העברת פרמטר לפונקציה – by reference • בהגדרת הפרמטרים שהשיטה מקבלת מציינים ליד הפרמטר & • זהו למעשה מתן שם נוסף לארגומנט המקורי שנשלח הנגיש מתוך הפונקציה • אין הבדל סינטקטי בשליחת המשתנה בעבור משתנה שעובר by value או by reference

  43. העברה by value – דוגמא: swap המטרה: פונקציה המקבלת 2 מספרים ומחליפה בינהם void swap(int a, int b) { cout << "In function, before swap: a=“ << a << “ b=“ << b << endl; int temp = b; b = a; a = temp; cout << "In function, after swap: a=“ << a << “ b=“ << b << endl; } void main() { int num1=2, num2=3; cout << "In main, before swap: num1=“ << num1 << “, num2=“ << num2; swap(num1, num2); cout << "In main, after swap: num1=“ << num1 << “, num2=“ << num2; } הפונקציה לא באמת החליפה בין הערכים... הזיכרון של swap הזיכרון של ה- main

  44. הדוגמא swap void swap(int& a, int& b) { int temp = a; a = b; b = temp; { void main() } int x=3, y=5; cout << "Before swap: x = " << x << ", y = " << y << "\n"; swap(x, y); cout << "After swap: x = " << x << ", y = " << y << "\n"; { הזכרון של ה- swap הזכרון של ה- main

  45. החזרת יותר מערך יחיד מפונקציה • למשל נרצה לכתוב פונקציה המקבלת מערך, וצריכה להחזיר מהו המספר המקסימאלי ומה המינימאלי • הפתרון: העברה לפונקציה פרמטר שעתיד להחזיק את התוצאה הסופית

  46. מציאת מינימום ומקסימום void minMax(int arr[], int size, int& min, int& max) { int i; min = max = arr[0]; for ( ; ; ) } if (min > arr[i]) min = arr[i]; if (max < arr[i]) max = arr[i]; } } void main() { int arr[] = {5,2,8}; int minimum, maximum; minMax(arr, sizeof(arr)/sizeof(arr[0]), minimum, maximum); cout << "max is “ << maximum << “ and min is “ << minimum << endl; } i=1 i < size i++ הזיכרון של minMax תזכורת: כאשר מעבירים מערך לפונקציה מתייחסים למערך המקורי, ולא לעותק שלו! הזיכרון של ה- main

  47. הארות • ניתן היה להעביר לפונקציה רק את min או רק את max ואת הערך השני להחזיר ע"י return • אבל: כאשר הפונקציה מחזירה יותר מערך אחד והם כולם בעלי אותה תפקיד, נעדיף שכולם יוחזרו by ref(אחידות בסגנון) • אם מעבירים לפונקציה פרמטר by ref שהפונקציה מתבססת על ערכו, חובה לאתחלו בפונקציה, ולא להתבסס על אתחול (שאולי) בוצע בפונקציה שקראה

  48. אתחול פרמטר המועבר by ref void countPositive(int arr[], int size, int& count) { int i; count = 0;// it is our responsibility to // initialize the value! for ( ; ; ) { if (arr[i] > 0) count++; } } void main() { int arr[] = {-4,2,-8}; int numOfPositive;// we can’t assume that who wrote // the main initialized that variable!! countPositive(arr, sizeof(arr)/sizeof(arr[0]), numOfPositive); cout << "There are “ << numOfPositive << “ positive numbers in the array\n”; } i=0 i < size i++ הזיכרון של countPositive הזיכרון של ה- main

  49. תזכורת למשמעות של העברה by value void incNumber(int x) { cout << "In function: number before: “ << x << endl; x++; cout << "In function: number after: “ << x << endl; { void main() } int num = 3; cout << "In main: number before function: “ << num << endl; incNumber(num); cout << "In main: number after function: “ << num << endl; { הזיכרון של incNumber הזיכרון של main

  50. מערכים כפרמטר לפונקציה - דוגמא void incArray(int arr[], int size) { for (int i=0 ; i < size ; i++) arr[i]++; } void printArray(int arr[], int size) { for (int i=0 ; i < size ; i++) cout << arr[i] << “ “; cout << endl; } void main() { int arr[] = {4,3,8}; int size = sizeof(arr)/sizeof(arr[0]); cout << "Orig array: “; printArray(arr, size); incArray(arr, size); cout << "Array after increment: “; printArray(arr, size); }

More Related