C++/פונקציות: הבדלים בין גרסאות בדף
תוכן שנמחק תוכן שנוסף
Ybungalobill (שיחה | תרומות) אין תקציר עריכה |
פונקציות |
||
שורה 15:
</source>
{{הארה|הפונקציה atan2 מקבלת שיעורי ווקטור ומחזירה את הזווית שבין הווקטור לבין ציר ה-x. תפקידה דומה ל-atan(y/x)‎ מלבד ש-atan2 עובדת באופן תקין גם כאשר שיעור ה-x שווה ל-0. פונקציות מתמתיות אלה נמצאות בספרייה <cmath>.}}
בדוגמה זו קראנו לפונקציה בשם atan2. שני הפרמטרים שנתנו לפונקציה הם y ו-x. כיוון שהפונקציה מחזירה ערך, אנחנו שמרנו אותו במשתנה alpha. כמו כן לאו דווקא יש לשמור את הערך שמחזירה פונקציה. קיימות פונקציות רבות שהערך המוחזר הוא לא המטרה שעבורה נקראתה הפונקציה, בעיקר כשערך זה מסמל שגיאה. לדוגמה הפונקציה הנפוצה שמשמשת את מתכנתי C לקלט, שמה scanf, מחזירה את מספר הערכים שנקלטו בהצלחה. למרות זאת,
חשוב להבין שלעומת שפות אחרות, כמו Pascal למשל, הקריאה לפונקציה '''לא''' נעשת כאשר אנו כותבים את שמה. הפונקציה נקראת על ידי אופרטור קריאה לפונקציה (). אופרטור זה מיוחד בכך
נכתוב בפרק זה פונקציה שמטרתה תהיה לעגל מספר שיבוא בפרמטר הראשון אל הכפולה הקרובה ביותר של חזקה של 10. החזקה של 10 אליה יש לעגל תבוא בפרמטר השני. הפונקציה תחזיר את התוצאה לאחר העיגול. נקרא לפונקציה זו בשם roundTo. לדוגמה נביא מספר קריאות לפונקציה זו:
שורה 27:
</source>
הפלט התקין צריך להיות:
<div style="direction: ltr;">
16, 20, 0, 100
</div>
== הגדרת פונקציות ==
{{הערה|הכרזה או הגדרה של הפונקציה תעשה לפני השימוש הראשון בה. טרם למדנו על הכרזות יש לכתוב את הגדרת הפונקציה לפני פונקציית ה-main.}}
=== כותרת הפונקציה ===
שורה 38 ⟵ 40:
* '''הטיפוס של הערך המוחזר מהפונקציה''' – זהו טיפוס כלשהו, מובנה או מוגדר על ידי המתכנת. ניתן במקום זאת לרשום את המילה השמורה void שפירושה שהפונקציה '''לא''' מחזירה ערך.
* '''שם הפונקציה''' – הכללים לבחירת שם הפונקציה זהים לכללים לבחירת כל שם אחר ב-C++‎. נשתמש בשם זה על מנת לקרוא לפונקציה משאר התוכנית.
* '''טיפוסים ושמות הפרמטרים''' – רשימה זו תבוא בסוגריים אחרי שם הפונקציה. כל פרמטר יהיה מופרד בפסיקים משאר הרשימה. הגדרת פרמטרים אלה דומה להגדרה של משתנים
להלן כדוגמה כותרת הפונקציה שנכתוב בפרק זה:
שורה 67 ⟵ 69:
=== הוראת return ===
על מנת להחזיר ערך מהפונקציה נשתמש בהוראת return. הוראה זו מחזירה את ערך הביטוי שנכתב אחריה. בדוגמה שלמעלה אנחנו מחזירים את ערכו של המשתנה result, כמו כן, ניתן היה להסתדר גם בלעדיו: לכתוב את הביטוי אחרי המילה השמורה return ובכך להחזיר ישירות את
את הוראת ה-return ניתן לכתוב לאו דווקא בסוף הפונקציה. כאשר מבוצעת הוראת ה-return מכל מקום אחר בתוך גוף הפונקציה היא מפסיקה את ביצוע העתידי שלה, במילים אחרות התוכנית יוצאת מהפונקציה. תכונה זו של הוראה זו מאפשרת את קיצור הקוד ומניעת קינון תנאים, בדומה להוראת break.
כל פונקציה שבכותרתה מצויין טיפוס הערך המוחזר חייבת להחזיר ערך, כלומר בכל פונקצייה שטיפוס הערך המוחזר הוא לא void חייבת לכלול הוראת return שבה תסתיים ריצתה. לדוגמה הפונקציה הבאה תקינה:
<source lang="cpp">
int f()
{
int n;
for(;;)
{
cout << "Enter a positive integer:\n";
cin >> n;
if(n > 0)
return n;
cout << "It's not positive! ";
}
}
</source>
בסוף גוף הפונקציה אין הוראת return, אבל התוכנית אף פעם לא תגיע לסוף בלוק הפונקציה מהסיבה שהיא מכילה לולאה אינסופית. הלולאה תיפסק רק כאשר תתבצעה הוראת ה-return שתצא מתוך הפונקציה ולכן ההוראה האחרונה שתתבצעה תהיה תמיד הוראת ה-return. לעומת זאת הפונקציה הבאה לא תקינה:
<source lang="cpp">
int f()
{
int n;
cout << "Enter a positive integer:\n";
cin >> n;
if(n > 0)
return n;
cout << "It's not positive! ";
}
</source>
הסיבה היא שכאשר התוכנית תקלוט מספר שלילי היא תגיע לסוף הפונקציה, לא תמצא את הוראת ה-return ולא תדע איזה ערך להחזיר. מהדר טוב צריך להתריע על העדר הוראות ה-return.
=== טיפוס void ===
שורה 75 ⟵ 110:
== הכרזת פונקציות ==
לפני שנוכל להשתמש בשם כלשהו ב-C++‎, לרוב, תחילה נצטרך להכריז עליו או להגדיר אותו. במילים אחרות, המהדר שקורא את קבצי התוכנית מהתחלה עד הסוף, צריך להתקל כבר בהכרזת שם זה על מנת להכיר אותו. '''ההכרזה''' אומרת למהדר שקיים שם מסויים (למשל i) ושיש להתייחס אליו כלדבר מסויים (למשל כלשם של משתנה מטיפוס int). דבר זה תקף גם עבור שמות הפונקציות. הפונקציות שנמצאות בספריות כלשהן
כאשר נכתוב פונקציה משלנו, נצטרך לפעמים להכריז עליה לפני שנשתמש בה. אנחנו חייבים להשתמש בהכרזה כאשר אנחנו מפרקים את התוכנית למודולים (למספר קבצי קוד, לרוב עם סיומת cpp), או כאשר אנחנו משתמשים בשתי פונקציות רקורסיביות הקוראות זו לזו (למד בהשמך). במקרה של תוכנית פשוטה בעלת קובץ אחד נוכל
ההכרזה תכיל את כותרת הפונקציה שתסתיים בנקודה פסיק. גוף הפונקציה לא יבוא בהכרזה מהסיבה הפשוטה שהוא זה שמבדיל בין הגדרה והכרזה. לדוגמה הכרזת הפונקציה roundTo תראה כך:
<source lang="cpp">
int roundTo(int number, int exponent);
</source>
הכרזת הפונקציה צריכה להכיל את אותו השם, אותו טיפוס מוחזר ואותם טיפוסי הפרמטרים כמו גם הגדרתה. כנאמר למעלה שמות הפרמטרים ניתנים אך ורק על מנת לפנות אליהם מתוך גוף הפונקציה עצמה, לכן כאשר אין בהם צורך נוכל למחוק אותם:
<source lang="cpp">
int roundTo(int, int);
</source>
כאשר כותבים את הקריאה לפונקציה סביבות פיתוח שונות נותנות רמזים שמכילים את כותרת הפונקציה. לכן כדאי בכל זאת לכתוב את שמותם המלאים של הפרמטרים כדי שנדע מה תפקיד הפרמטר הראשון ומה תפקיד הפרמטר השני, גם כששניהם מטיפוס int. כמו כן אם ניתנים שמות לפרמטרים הם לא חייבים להיות זהים בין ההכרזה וההגדרה.
== רקורסיה ==
שורה 85 ⟵ 131:
העמסת פונקציות (Overloading) היא יצירה של יותר מפונקציה אחת עם אותו שם, כאשר הן נבדלות זו מזו על ידי רשימת הפרמטרים שלהן.<br /> יש צורך באלמנט זה בכדי ליצור פונקציה אחת (בעצם כמה, בעלות שם זהה) שהיא רב שימושית, הוי אומר שלמשל פונקציה שמחזירה את הגדול מבין שני מספרים שמתקבלים כפרמטרים תהיה מתאימה למספר טיפוסי נתונים.<br /> למשל: היא תוכל לחשב את התוצאה גם אם יתקבלו משתנים מטיפוס int וגם אם יתקבלו משתנים מטיפוס double, ואפשר כמובן שיהיה שוני בין שני החישובים.
===דוגמה להעמסה===
כעת, נדגים את הרעיון ע"י העמסה של פונקציה המחזירה את סכומם של שני מספרים שנשלחו אליה כפרמטרים:
|