Issuu on Google+

‫קורס מבוא למדעי המחשב‬ ‫סמסטר א' תשס"ח‬

‫שיעור חמישי‪ :‬פונקציות‬

‫‪http://online.shenkar.ac.il/moodle‬‬

‫תזכורת‪ :‬לולאות‬ ‫•‬

‫לולאת ‪while‬‬ ‫•‬

‫מתבצעת שוב ושוב כל עוד תנאי מסויים מתקיים‬ ‫‪while (i <= 10) ….‬‬

‫•‬

‫לולאת ‪for‬‬

‫•‬

‫‪do‬‬‫לולאת ‪do-while‬‬

‫;‪for (i=1; i<=10; i++) cout << i << endl‬‬ ‫;‪endl‬‬ ‫•‬

‫•‬

‫‪ break‬ו‪continue -‬‬ ‫•‬ ‫•‬

‫•‬

‫‪ break‬מפסיקה את הלולאה‬ ‫‪ continue‬מסיימת את האיטרציה הנוכחית של הלולאה‬

‫לולאות מקוננות‬ ‫•‬

‫‪1‬‬

‫מתבצעת לפחות פעם אחת‪ ,‬וכל עוד התנאי מתקיים‬

‫לולאה בתוך לולאה‪ break ,‬ו‪ continue -‬מתייחסות לפנימית ביותר‬


‫ תזכורת‬- while 10 ‫ עד‬1 ‫הדפסת המספרים‬ #include <iostream.h > <iostream.h> void main() { int i=1;

while ( i <= 10) { cout << i << endl; endl; i++; } }

‫ תזכורת‬- do-while #include <iostream.h > <iostream.h> void main() {

10 ‫ עד‬1 ‫גם זה מדפיס את‬

int i=1; do { cout << i << endl; i++; } while (i<=10); }

2


‫ תזכורת‬- do-while #include <iostream.h > <iostream.h> void main() {

‫ בלבד‬11 ‫מדפיס את‬

int i=11; do { cout << i << endl; i++; } while (i<=10); }

for :‫תזכורת‬ 20 ‫ בחזקת‬2 ‫חישוב‬ #include <iostream.h > <iostream.h> void main() { int i,result=1 i,result=1; for(i=1; for(i=1; i<= i<=20; i++) result=result*2; cout << "2^20 = " << result << endl; endl; }

3


‫תזכורת‪ :‬לולאות מקוננות‬ ‫הדפסת ריבוע של כוכביות בגודל ‪:20X20‬‬

‫)‪for(i=1; i<=20; i++‬‬ ‫{‬ ‫;”*“ << ‪for(j=1; j<=20; j++) cout‬‬ ‫;‪cout << endl‬‬ ‫}‬

‫נקודה לתשומת לב ברישום תנאים‬ ‫• אפשר לרשום‪:‬‬ ‫)‪(0 >= x‬‬ ‫)‪(x >= 0‬‬ ‫אי‪-‬אפשר לרשום‪:‬‬

‫)‪(0 <= x‬‬

‫)‪(x =< 0‬‬

‫)‪(x <= 0‬‬ ‫)‪(x => 0‬‬

‫• כמו‪-‬כן‪ ,‬אל‪-‬תרשמו‪:‬‬ ‫)‪(5>x>0‬‬ ‫אלא‪:‬‬ ‫))‪((5>x) && (x>0‬‬

‫‪4‬‬


‫שאלות על השיעור הקודם?‬

‫שאלה‬ ‫• כיצד נוכל לחשב את הסכום הבא‪:‬‬

‫? =‪220+315+517‬‬

‫‪5‬‬


‫פתרון אפשרי‬ ‫‪#include <iostream.h‬‬ ‫>‬ ‫>‪<iostream.h‬‬ ‫)(‪void main‬‬ ‫{‬ ‫;‪int i‬‬ ‫אם היו יותר מחוברים ‪ -‬היינו‬ ‫‪double sum=0, result=1‬‬ ‫;‪result=1‬‬ ‫על‬ ‫ת‬ ‫צריכים לחזור פעמים נוספו‬ ‫=<‪for(i=1; i‬‬ ‫)‪i<=20; i++‬‬ ‫אותן שורות עם מספרים אחרים‬ ‫;‪result=result*2‬‬ ‫;‪sum +=result‬‬ ‫‪result=1‬‬ ‫;‪result=1‬‬ ‫=<‪for(i=1; i‬‬ ‫)‪i<=15; i++‬‬ ‫זה מאריך את התוכנית פי כמה‬ ‫;‪result=result*3‬‬ ‫וכמה‪ ,‬מסרבל אותה‪ ,‬ויוצר פתח‬ ‫;‪sum +=result‬‬ ‫לבאגים‬ ‫‪result=1‬‬ ‫;‪result=1‬‬ ‫=<‪for(i=1; i‬‬ ‫)‪i<=17; i++‬‬ ‫;‪result=result*5‬‬ ‫;‪sum +=result‬‬ ‫;‪cout << "2^20 + 3^15 + 5^17 = " << sum << endl‬‬ ‫;‪endl‬‬ ‫}‬

‫מה היינו רוצים?‬ ‫לכתוב פעם אחת את קטע התוכנית שחוזר על עצמו‪,‬‬ ‫ולהשתמש בו כמה פעמים‪ ,‬כל פעם עם נתונים שונים‪.‬‬

‫‪6‬‬


‫פיתרון אחר לחישוב‬ #include <iostream.h > <iostream.h> double power(double base, int exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; }

...‫זה בדיוק מה שרצינו‬

void main() { double solution=power(2,20)+power(3,15)+power(5,17); cout << "2^20 + 3^15 + 5^17 = " << solution << endl; endl; }

‫ דוגמא‬- ‫פונקציות‬ #include <iostream.h > <iostream.h> double power( power(double base, int exponent) exponent) { ,‫נותנים שם לקטע תוכנית מסויים‬ int i; ‫כך שאפשר להשתמש בו כמה‬ double result=1; ‫ כל פעם עם נתונים שונים‬,‫פעמים‬ for(i=1; i<=exponent; i++) "‫קטע תוכנית כזה נקרא "פונקציה‬ result=result*base; return result; :‫ריצת התוכנית תמיד תתחיל כאן‬ } void main() { double solution=power( power((3,15)+ power((5,17); power(2,20)+ 2,20)+power 3,15)+power 5,17); cout << "2^20 + 3^15 + 5^17 = " << solution << endl; endl; }

7


‫פונקציות ‪ -‬דוגמא‬ ‫‪#include <iostream.h‬‬ ‫>‬ ‫>‪<iostream.h‬‬ ‫(‪double power‬‬ ‫)‪power(double base, int exponent‬‬ ‫)‪exponent‬‬ ‫{‬ ‫נותנים שם לקטע תוכנית מסויים‪,‬‬ ‫;‪int i‬‬ ‫כך שאפשר להשתמש בו כמה‬ ‫;‪double result=1‬‬ ‫פעמים‪ ,‬כל פעם עם נתונים שונים‬ ‫)‪for(i=1; i<=exponent; i++‬‬ ‫קטע תוכנית כזה נקרא "פונקציה"‬ ‫;‪result=result*base‬‬ ‫;‪return result‬‬ ‫ריצת התוכנית תמיד תתחיל כאן‪:‬‬ ‫}‬

‫הפונקציה נקראת )מחושבת( כל פעם עבור‬ ‫הערכים המתאימים‪ ,‬והתוצאות מוחזרות‬

‫)(‪void main‬‬ ‫{‬

‫(‪double solution=power‬‬ ‫‪power((3,15)+‬‬ ‫;)‪power((5,17‬‬ ‫‪power(2,20)+‬‬ ‫‪2,20)+power‬‬ ‫‪3,15)+power‬‬ ‫;)‪5,17‬‬ ‫;‪cout << "2^20 + 3^15 + 5^17 = " << solution << endl‬‬ ‫;‪endl‬‬ ‫}‬

‫פונקציות – הסבר כללי‬

‫‪8‬‬

‫•‬

‫פונקציה היא קטע תוכנית שיש לו שם‪ ,‬ויכול לקבל ערכי קלט ולתת ערך‬ ‫פלט‪.‬‬

‫•‬

‫כמו משתנים‪ ,‬צריך להגדיר פונקציות לפני שמשתמשים בהן‪.‬‬

‫•‬

‫הגדרת הפונקציה כוללת‪ ,‬בנוסף לשם ולפקודות‪ ,‬את סוגי הנתונים‬ ‫שהפונקציה מקבלת‪ ,‬ואת סוג הנתונים שהפונקציה מחזירה‪.‬‬

‫•‬

‫אפשר להשתמש באותה פונקציה הרבה פעמים‪ ,‬כל פעם עם הנתונים‬ ‫המתאימים‪.‬‬

‫•‬

‫‪.cout,‬‬ ‫‪cout, cin,‬‬ ‫‪cin, printf,‬‬ ‫לדוגמא‪printf, scanf :‬‬


‫פונקציות ‪ -‬דוגמא‬ ‫‪#include <iostream.h‬‬ ‫>‬ ‫>‪<iostream.h‬‬ ‫(‪double power‬‬ ‫)‪power(double base, int exponent‬‬ ‫)‪exponent‬‬ ‫{‬ ‫נותנים שם לקטע תוכנית מסויים‪,‬‬ ‫;‪int i‬‬ ‫כך שאפשר להשתמש בו כמה‬ ‫;‪double result=1‬‬ ‫פעמים‪ ,‬כל פעם עם נתונים שונים‬ ‫)‪for(i=1; i<=exponent; i++‬‬ ‫קטע תוכנית כזה נקרא "פונקציה"‬ ‫;‪result=result*base‬‬ ‫;‪return result‬‬ ‫ריצת התוכנית תמיד תתחיל כאן‪:‬‬ ‫}‬

‫הפונקציה נקראת )מחושבת( כל פעם עבור‬ ‫הערכים המתאימים‪ ,‬והתוצאות מוחזרות‬

‫)(‪void main‬‬ ‫{‬

‫(‪double solution=power‬‬ ‫‪power((3,15)+‬‬ ‫;)‪power((5,17‬‬ ‫‪power(2,20)+‬‬ ‫‪2,20)+power‬‬ ‫‪3,15)+power‬‬ ‫;)‪5,17‬‬ ‫;‪cout << "2^20 + 3^15 + 5^17 = " << solution << endl‬‬ ‫;‪endl‬‬ ‫}‬

‫פונקציות – נושאי השיעור היום‬ ‫•‬ ‫•‬ ‫•‬ ‫•‬ ‫•‬

‫‪9‬‬

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


‫סיבות לשימוש בפונקציות‬ ‫• אמרנו‪ :‬כשרוצים להשתמש באותו קטע תוכנית כמה‬ ‫פעמים בתוכנית )יתכן שעם נתונים שונים(‪.‬‬ ‫• כדי לחלק את התוכנית לחלקים‪ ,‬שכל אחד מהם מבצע‬ ‫חלק לוגי מסויים )קריאת הקלטים‪ ,‬עיבוד‪ ,‬הדפסת‬ ‫פלטים‪ ,‬וכד'(‪.‬‬ ‫• קשה לכתוב ולתחזק פונקציית ‪ main‬ארוכה שהכל נעשה בתוכה‪.‬‬ ‫מקובל לחלק לפונקציות בהתאם לחלקים הלוגיים ולכתוב פונקציית‬ ‫‪ main‬קצרה שבעיקר קוראת לפונקציות אחרות‪.‬‬

‫סיבות לשימוש בפונקציות‬ ‫• כדי להשתמש בחלק מתוכנית שכתבנו בתוכניות‬ ‫אחרות שנכתוב‪.‬‬ ‫•‬

‫•‬

‫‪10‬‬

‫נוכל להכין ספריות של פונקציות שימושיות שכתבנו‬ ‫ולהשתמש בהן בתוכניות אחרות שנכתוב‪.‬‬ ‫יש כבר ספריות מוכנות כאלה ב‪ ,C -‬כמו ‪.iostream.h‬‬


‫הגדרת פונקציות‬ ‫•‬

‫הגדרת פונקציה מבוצעת באופן הבא‪:‬‬ ‫)הגדרת משתנים לערכים שמועברים לפונקציה( שם הפונקציה טיפוס הערך המוחזר‬ ‫{‬ ‫פקודות הפונקציה‬ ‫הערך המוחזר ‪return‬‬ ‫}‬

‫•‬

‫למשל‪:‬‬

‫‪double power(double‬‬ ‫)‪power(double base, int exponent‬‬ ‫)‪exponent‬‬ ‫{‬ ‫;‪int i‬‬ ‫בתוך פונקציה אפשר לעשות כל מה‬ ‫;‪double result=1‬‬ ‫שאפשר לעשות ב‪ :main -‬להגדיר‬ ‫)‪for(i=1; i<=exponent; i++‬‬ ‫משתנים ולבצע פקודות )כולל להפעיל‬ ‫;‪result=result*base‬‬ ‫פונקציות(‪.‬‬ ‫;‪return result‬‬ ‫}‬

‫הגדרת פונקציות – שם הפונקציה‬

‫‪11‬‬

‫•‬

‫חלים עליו אותם כללים כמו שם של משתנה‪.‬‬

‫•‬

‫בפרט‪ ,‬הוא לא יכול להכיל סימנים )כמו ‪ %$*-+‬וכד'(‪ ,‬חייב‬ ‫להתחיל באות‪ ,‬ואסור לו להיות מילה שמורה )אסור ‪ ,for,if‬וכו'(‪.‬‬

‫•‬

‫בדומה למשתנים‪ ,‬חשוב ששם הפונקציה יהיה משמעותי ויעיד‬ ‫על תפקידה‪.‬‬

‫•‬

‫דוגמאות לשמות‪:‬‬

‫‪max, print_table, is_prime‬‬


‫הגדרת פונקציות‪void :‬‬ ‫• אם הפונקציה לא מקבלת ערכים‪ ,‬אפשר להשאיר את‬ ‫הסוגריים ריקים או לכתוב בתוכם ‪.void‬‬ ‫)‪int print_hello(void‬‬ ‫• למשל‪:‬‬ ‫• אם הפונקציה לא מחזירה ערכים‪ ,‬צריך לכתוב ‪void‬‬ ‫בתור טיפוס הערך המוחזר )אם לא רושמים שם כלום‬ ‫זה מתפרש כ‪.(int -‬‬ ‫•‬

‫למשל‪:‬‬

‫)‪void print_hello(void‬‬

‫פונקציות – סיום הפונקציה‬ ‫•‬

‫•‬

‫•‬

‫‪12‬‬

‫אם הפונקציה אמורה להחזיר ערך‪ ,‬צריך לסיים אותה על‪-‬ידי‬ ‫פקודת ‪ ,return‬שבה מוחזר ערך מטיפוס מתאים )ריצת‬ ‫הפונקציה נפסקת ע"י פקודת ‪.(return‬‬ ‫אפשר לתת כמה אפשרויות לחזרה‪ ,‬למשל‪:‬‬ ‫)‪int greater(int a, int b‬‬ ‫{‬ ‫;‪if (a>b) return 1‬‬ ‫;‪1‬‬ ‫;‪else return 0‬‬ ‫;‪0‬‬ ‫}‬ ‫עם סיום ריצת הפונקציה‪ ,‬חוזרים למקום שממנו הפונקציה‬ ‫נקראה‪ .‬כל המשתנים שלה מתבטלים ולא מוגדרים יותר‪.‬‬


‫הקריאה לפונקציה‬ ‫•‬

‫בקריאה לפונקציה צריך להעביר אליה ערכים בהתאם‬ ‫לטיפוסים שנקבעו בהגדרה שלה‪.‬‬ ‫•‬ ‫•‬

‫•‬

‫‪power(5,10‬‬ ‫למשל‪power(5,10)) :‬‬ ‫אפשר להעביר שלם במקום ממשי‪ ,‬אבל לא להיפך‪.‬‬

‫עם סיום הפונקציה‪ ,‬יוחזר הערך שהפונקציה החזירה‪ ,‬וניתן‬ ‫לבצע עליו פעולות או לשמור אותו במשתנה‪.‬‬ ‫•‬

‫למשל‪:‬‬

‫)‪a=32*(power(b,5)+17‬‬ ‫‪d=sqrt(c‬‬ ‫))‪d=sqrt(c‬‬

‫פונקציות ‪ -‬דוגמא‬ ‫‪#include <iostream.h‬‬ ‫>‬ ‫>‪<iostream.h‬‬ ‫(‪double power‬‬ ‫)‪power(double base, int exponent‬‬ ‫)‪exponent‬‬ ‫{‬ ‫;‪int i‬‬ ‫;‪double result=1‬‬ ‫)‪for(i=1; i<=exponent; i++‬‬ ‫;‪result=result*base‬‬ ‫;‪return result‬‬ ‫פעם עבור‬ ‫}‬

‫הפונקציה נקראת )מחושבת( כל‬ ‫הערכים המתאימים‪ ,‬והתוצאות מוחזרות‬

‫)(‪void main‬‬ ‫{‬ ‫(‪double solution=power‬‬ ‫‪power((3,15)+‬‬ ‫;)‪power((5,17‬‬ ‫‪power(2,20)+‬‬ ‫‪2,20)+power‬‬ ‫‪3,15)+power‬‬ ‫;)‪5,17‬‬ ‫;‪cout << "2^20 + 3^15 + 5^17 = " << solution << endl‬‬ ‫;‪endl‬‬ ‫}‬

‫‪13‬‬


‫פונקציית ‪main‬‬ ‫•‬

‫כל תוכנית ‪ C‬מכילה פונקציה בשם ‪ ,main‬שבה התוכנית מתחילה‪.‬‬

‫•‬

‫הערך שמוחזר ממנה מועבר למערכת ההפעלה‪ .‬טיפוסו צריך להיות‬ ‫‪ .int‬אם ערכו ‪ 0‬המשמעות היא שהתוכנית הסתיימה באופן תקין‪.‬‬

‫•‬

‫פונקציית ‪ main‬יכולה גם לקבל משתנים ממערכת ההפעלה )ערכים‬ ‫שנכתבים בשורת הפקודה כשמריצים את התוכנית(‪ ,‬אבל יכולה‬ ‫לפעול גם בלי לקבל משתנים‪.‬‬ ‫)(‪int main‬‬ ‫)(‪main‬‬ ‫{‬ ‫\!‪cout << “Hello World‬‬ ‫;”‪World!\n‬‬ ‫;‪return 0‬‬ ‫}‬

‫פונקציית ‪main‬‬ ‫•‬

‫כל תוכנית ‪ C‬מכילה פונקציה בשם ‪ ,main‬שבה התוכנית מתחילה‪.‬‬

‫•‬

‫הערך שמוחזר ממנה מועבר למערכת ההפעלה‪ .‬טיפוסו צריך להיות‬ ‫‪ .int‬אם ערכו ‪ 0‬המשמעות היא שהתוכנית הסתיימה באופן תקין‪.‬‬

‫•‬

‫פונקציית ‪ main‬יכולה גם לקבל משתנים ממערכת ההפעלה )ערכים‬ ‫שנכתבים בשורת הפקודה כשמריצים את התוכנית(‪ ,‬אבל יכולה‬ ‫לפעול גם בלי לקבל משתנים‪.‬‬ ‫)(‪int main‬‬ ‫)(‪main‬‬ ‫{‬ ‫\!‪cout << “Hello World‬‬ ‫\!‪“Hello World‬‬ ‫(‪World!\n”; /*printf‬‬ ‫“(‪/*printf‬‬ ‫‪World!\n”);*/‬‬ ‫;‪return 0‬‬ ‫}‬

‫‪14‬‬


‫פונקציות ‪ -‬סיכום‪-‬ביניים‬ ‫• הגדרת פונקציה‬ ‫• סיום הריצה של פונקציה‬ ‫• קריאה לפונקציה‬ ‫• שאלות?‬

‫המשתנים בפונקציה‬

‫‪15‬‬

‫•‬

‫משתנים שמוגדרים בתוך פונקציה הם מקומיים )לוקאליים(‬ ‫��ק לפונקציה הזאת‪.‬‬

‫•‬

‫הם לא מוגדרים בפונקציות אחרות )אפשר להגדיר בפונקציות‬ ‫אחרות משתנים אחרים באותו שם(‪.‬‬

‫•‬

‫זה כולל גם את המשתנים שאליהם מועברים ערכים עבור‬ ‫הפונקציה )גם הם מקומיים(‪.‬‬

‫•‬

‫חשוב להדגיש‪ :‬בסיום ריצת פונקציה משתניה לא מוגדרים‬ ‫יותר‪ ,‬וערכיהם לא נשמרים‪.‬‬


‫דוגמא‬- ‫משתנים בפונקציה‬ #include <iostream.h > <iostream.h> double power(double power(double base, int exponent) exponent) { int i; double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; } void main() { double solution=power(2,20 )+power(3,15 3,15)+power( )+power(5,17 5,17); ); power(2,20)+power( cout << "2^20 + 3^15 + 5^17 = " << solution << endl; endl; }

‫דוגמא‬- ‫משתנים בפונקציה‬ #include <iostream.h > <iostream.h> double power(double power(double base, int exponent) exponent) { base, exponent, i, result int i; power ‫מוגדרים רק בתוך הפונקציה‬ double result=1; for(i=1; i<=exponent; i++) result=result*base; return result; }

solution ‫המשתנה‬ int main() {

main ‫מוגדר רק בתוך הפונקציה‬

double solution=power(2,20 )+power(3,15 3,15)+power( )+power(5,17 5,17); ); power(2,20)+power( cout << "2^20 + 3^15 + 5^17 = " << solution << endl; endl; return 0; }

16


‫ דוגמא‬- ‫משתנים בפונקציה‬ #include <iostream.h > <iostream.h> double power(double base, int exponent) {

i

int ; double result=1;

i

i

i

for( =1; <=exponent; ++) result=result*base; return result;

‫אפשר להגדיר בפונקציות שונות‬ ‫ והם אינם‬,‫משתנים באותו שם‬ ‫קשורים זה לזה‬

} int main() {

i

double =power(2,20)+power(3,15)+power(5,17);

i

cout << "2^20 + 3^15 + 5^17= " << << endl; endl; return 0; }

‫פונקציות – העברת ערכים‬ ‫ שינויים‬.‫ לפונקציה מועברים ערכים – לא משתנים‬:‫נשים לב‬ .‫במשתנה שאליו הוכנס הערך לא משפיעים על המשתנה המקורי‬ :‫למשל בדוגמא הבאה‬ #include<iostream.h > #include<iostream.h> int square (int num) { num=num*num; return num; }

• •

:‫הפלט‬ The square of 16 is 256

int main() { int num=16; cout<<"The <" is "<<square cout<<"The square of "<<num "<<num<" "<<square((num); num); return 0; }

17


‫פונקציות – העברת ערכים‬ ‫•‬ ‫•‬

‫נשים לב‪ :‬לפונקציה מועברים ערכים – לא משתנים‪ .‬שינויים‬ ‫במשתנה שאליו הוכנס הערך לא משפיעים על המשתנה המקורי‪.‬‬ ‫למשל בדוגמא הבאה‪:‬‬

‫הפלט‪:‬‬ ‫‪The square of 16 is 256‬‬

‫‪#include<iostream.h‬‬ ‫>‬ ‫>‪#include<iostream.h‬‬ ‫)‪int square (int num‬‬ ‫{‬ ‫;‪num=num*num‬‬ ‫;‪return num‬‬ ‫}‬

‫)(‪int main‬‬ ‫כאן מועבר הערך ‪16‬‬ ‫{‬ ‫;‪int num=16‬‬ ‫‪cout<<"The‬‬ ‫‪<" is "<<square‬‬ ‫;;‪endl‬‬ ‫‪cout<<"The square of "<<num‬‬ ‫"<‪"<<num‬‬ ‫<<)‪"<<square((num‬‬ ‫‪num)<<endl‬‬ ‫;‪return 0‬‬ ‫המשתנה ‪ num‬שב‪ main -‬לא‬ ‫}‬

‫מושפע מהשינויים במשתנה‬ ‫שאליו הועבר ערכו‬

‫משתנים גלובליים‬

‫‪18‬‬

‫•‬

‫אפשר‪ ,‬אבל לא מומלץ‪ ,‬להגדיר משתנים בתחילת הקובץ‪ ,‬לא‬ ‫בתוך אף פונקציה‪ .‬במקרה כזה הם יהיו מוגדרים בכל הפונקציות‬ ‫שמופיעות בקובץ‪ .‬זה נקרא "משתנים גלובליים"‪.‬‬

‫•‬

‫זה לא מומלץ כי זה עלול ליצור באגים )עושים שינוי בפונקציה‬ ‫אחת ולא שמים לב שזה משפיע על פונקציה אחרת(‪ ,‬ופוגע‬ ‫בהפרדה הלוגית בין הפונקציות‪.‬‬


‫ דוגמא‬- ‫משתנים גלובליים‬ #include<iostream.h > #include<iostream.h> int k; int square_k() {return k*k;} k*k;} int main() ‫אין צורך להעביר את הערך‬ { cout << "Enter the number to square\ square\n": cin >> k; cout<<"The ()<<endl endl;; cout<<"The square of "<<k "<<k<" is "<<square_k "<<square_k()<< return 0; }

‫ דוגמא‬- ‫משתנים גלובליים‬ #include<iostream.h > #include<iostream.h> int k;

‫כאמור – צריך להכיר אבל‬ ‫עדיף לא להשתמש‬

int square_k() {return k*k;} k*k;} int main() { cout << "Enter the number to square\ square\n": cin >> k; cout<<"The ()<<endl endl;; cout<<"The square of "<<k "<<k<" is "<<square_k "<<square_k()<< return 0; }

19


‫פונקציות – משתנים סטטיים‬ ‫•‬

‫אמרנו שכל המשתנים של הפונקציה נעלמים עם סיומה‪.‬‬

‫•‬

‫מה נעשה אם הפונקציה צריכה לדעת כמה פעמים קראו לה‬ ‫עד כה? )למשל אם מהפעם העשירית זה בתשלום(‬

‫•‬

‫פתרון אפשרי הוא משתנה גלובלי שהפונקציה תוסיף לו ‪ 1‬כל‬ ‫פעם בתחילת הריצה שלה‪ .‬אבל אמרנו שעדיף לא להשתמש‬ ‫במשתנים גלובליים‪.‬‬

‫פונקציות – משתנים סטטיים‬ ‫•‬

‫אפשר להגדיר משתנים בפונקציה שערכם ישמר ולא יעלם‬ ‫בסוף ריצת הפונקציה‪" :‬משתנים סטטיים"‪.‬‬

‫•‬

‫מוסיפים את המילה ‪ static‬לפני ההגדרה שלהם‪:‬‬

‫;‪static int counter=0‬‬ ‫•‬

‫‪20‬‬

‫הם מאותחלים פעם אחת בקריאה הראשונה לפונקציה‪,‬‬ ‫ובקריאות הבאות הם שומרים על ערכם מסוף הריצה‬ ‫הקודמת שלה )אבל הם מוגדרים רק בתוך הפונקציה(‪.‬‬


‫משתנים סטטיים ‪ -‬דוגמא‬ ‫• הפונקציה הבאה מחזירה את מספר הפעמים שקראו‬ ‫לה עד כה‪:‬‬

‫יאותחל רק בקריאה הראשונה‬ ‫בכל קריאה יתווסף ‪ 1‬לערכו הקודם‬

‫)(‪int n_calls‬‬ ‫{‬ ‫;‪static int counter=0‬‬ ‫;‪counter++‬‬ ‫;‪return counter‬‬ ‫}‬

‫קבועים‬ ‫•‬

‫הזכרנו בעבר שאפשר להגדיר משתנה שערכו יישאר קבוע על‪-‬‬ ‫ידי תוספת המילה ‪:const‬‬ ‫‪const double pi=3.1415‬‬ ‫•‬

‫•‬

‫•‬

‫אם רוצים להגדיר ערכים קבועים שיהיו בשימוש כל חלקי‬ ‫התוכנית‪ ,‬אין צורך במשתנה גלובלי‪ ,‬וניתן להגדיר קבוע על‪-‬ידי‪:‬‬ ‫‪#define pi 3.1415‬‬ ‫•‬

‫‪21‬‬

‫אמרנו שמעדיפים לראות בתוכנית שמות משמעותיים של קבועים‬ ‫מאשר מספרים שמקורם לא ברור‪.‬‬ ‫אבל אמרנו שמשתנה יוגדר רק בתוך פונקציה מסויימת‪.‬‬

‫זו פקודה ל‪ preprocessor -‬שמחליפה את המילה ‪ pi‬במספר‬ ‫‪ 3.1415‬בכל התוכנית לפני תחילת התרגום לשפת מכונה‪.‬‬


‫המשתנים בפונקציה‬ ‫• משתנים מקומיים )לוקאליים(‬ ‫• העברת ערכים לפונקציה‬ ‫• משתנים גלובליים ומשתנים סטטיים‬ ‫• קבועים‬ ‫• שאלות?‬

‫הכרזה על פונקציות‬

‫‪22‬‬

‫•‬

‫אמרנו שכדי להשתמש בפונקציה‪ ,‬צריך שהיא תהיה מוגדרת‪.‬‬

‫•‬

‫לכן רשמנו תמיד את הפונקציה לפני ה‪ ,main -‬שבו השתמשנו‬ ‫בה‪.‬‬

‫•‬

‫אופציה נוספת היא לרשום הכרזה )‪ (declaration‬של הפונקציה‬ ‫בתחילת הקובץ‪ ,‬ולרשום את המימוש שלה )‪ (definition‬בסופו‪,‬‬ ‫או בקובץ נפרד‪.‬‬


‫הכרזה על פונקציות‬ ‫•‬

‫דוגמא להכרזה )‪:(declaration, prototype‬‬ ‫;)‪double power(double base, int exponent‬‬

‫ומותר גם בלי שמות המשתנים‪:‬‬ ‫;)‪double power(double, int‬‬ ‫;)‪int‬‬ ‫כשרק בסוף הקובץ נרשום את ההגדרה המלאה )‪:(definition‬‬ ‫)‪double power(double base, int exponent‬‬ ‫{‬ ‫;‪int i‬‬ ‫;‪double result=1‬‬ ‫)‪for(i=1; i<=exponent; i++‬‬ ‫;‪result=result*base‬‬ ‫;‪return result‬‬ ‫}‬

‫הכרזה על פונקציות – למה זה טוב‬

‫‪23‬‬

‫•‬

‫לפעמים נוח לראות בתחילת הקובץ את הפונקציות העיקריות‬ ‫ולהשאיר את פונקציות העזר בסוף‪.‬‬

‫•‬

‫הרבה פעמים התוכנית מחולקת לכמה קבצים שאומרים‬ ‫לקומפיילר לצרף יחד‪ ,‬ואז ההגדרה )המימוש( של הפונקציה‬ ‫צריכה להופיע רק באחד מהם‪ ,‬ובאחרים מופיעה רק ההכרזה‪.‬‬

‫•‬

‫בפרט‪ ,‬זה המצב כשאנחנו משתמשים בספריות של פונקציות‪,‬‬ ‫כמו ‪.iostream.h‬‬


‫הכרזה על פונקציות – ספריות‬ ‫•‬

‫‪ #include<iostream.h‬פשוט אומרת לקומפיילר‬ ‫השורה >‬ ‫>‪#include<iostream.h‬‬ ‫לצרף לתחילת הקובץ שלנו את הקובץ ‪ iostream.h‬מתוך קבצי‬ ‫ההכרזות של ‪.C‬‬

‫•‬

‫הקובץ הזה מכיל הכרזות של פונקציות קלט‪/‬פלט שימושיות‬ ‫)כמו ‪.(cout,cin‬‬

‫•‬

‫כך אנחנו יכולים להשתמש בהן בתוכנית שלנו בלי להכיר את‬ ‫המימוש שלהן‪ ,‬ואחרי הקומפילציה הלינקר )מקשר( מצרף את‬ ‫המימוש מתוך הספריות הקיימות של ‪.C‬‬

‫ספריות נוספות‬ ‫• ב‪ C -‬יש ספריות נוספות שנוכל להשתמש בהן‪ .‬למשל‬ ‫ב‪ math.h -‬נוכל למצוא פונקציות כמו‬ ‫‪) sin,cos,tan,abs,fabs,log,sqrt,pow‬תינתן רשימה‬ ‫בתירגול(‪.‬‬ ‫• ב‪ ctype.h -‬יש פונקציות שעוסקות בסוג של תווים‪ ,‬כמו‬ ‫‪ ,islower, toupper‬ועוד‪.‬‬ ‫• נכיר עם הזמן ספריות נוספות‪.‬‬

‫‪24‬‬


‫סיכום‬ ‫דיברנו היום על‪:‬‬ ‫• מהן פונקציות ולמה הן שימושיות‬ ‫• קריאה לפונקציה והערך שמוחזר ממנה‬ ‫• משתנים בפונקציות והעברת ערכים אליהן‬ ‫• הכרזה על פונקציות וספריות של פונקציות‬

‫מבוא למדעי המחשב – שיעור חמישי‬

‫שאלות נוספות?‬

‫‪25‬‬


5 פונקציות