שגרה (תכנות) – הבדלי גרסאות

תוכן שנמחק תוכן שנוסף
Delta739 (שיחה | תרומות)
מ הגהה החלפת מטודה במתודה
שורה 1:
ב[[תכנות מחשבים]], '''שגרה''' (ב[[אנגלית]]: '''Subroutine''') או '''פרוצדורה''' (באנגלית: '''Procedure''') או '''מטודהמתודה''' (באנגלית '''Method''') היא רצף של [[פקודה (מחשב)|פקודות]] המאוגדות יחדיו, במטרה לבצע מטלה מוגדרת, מימוש של [[אלגוריתם]]. '''פונקציה''' היא שגרה המחזירה ערך. מטודותמתודות ופרוצדורה לא חייבות להחזיר ערכים לעומת פונקציה. במטודותבמתודות שמהן לא מוחזר ערך מבצעים הדפסות למסך, אתחול של אובייקט וכדומה.
 
'''קריאה''' למטודהלמתודה היא הפעלה שלה תוך כדי פעולת ה[[תוכנית מחשב|תוכנית]]. קריאה של שגרה לעצמה, ישירות או בעקיפין, נקראת [[רקורסיה]]. החלק במטודהבמתודה שמתבצע בפועל נקרא "גוף" המטודההמתודה. מטודהמתודה יכולה שלא לקבל קלט, לקבל קלט יחיד או מספר של קלטים כלשהם. בכל שפת תכנות קיימות מטודותמתודות או פונקציות, והן הבסיס של עולם התוכנה. הן אלו שגורמות לאובייקטים בתוכנה לפעול, להציג מידע, לשנות מידע ולתקשר עם אובייקטים אחרים.
 
שימוש בשגרות ובפונקציות משפר את מבנה התוכנית, את קריאות הקוד ואת מידת הגמישות של התוכנית לביצוע שינויים. על פי רוב, פונקציה או מטודהמתודה לא יכילו יותר מ-25 שורות של קוד. כך שאם מטודהמתודה לא עובדת כשורה יהיה קל יחסית לעבור על כל הקוד שמרכיב אותה ולמצוא בו טעויות. עובדה זו מאפשרת להפחית במידה משמעותית את עלויות הפיתוח והתחזוקה של תוכנה. ברוב [[שפת תכנות|שפות התכנות]] המודרניות ישנו שימוש נרחב בשגרות. שגרות נתמכות באופן בסיסי גם ב[[שפת סף|שפות סף]] ו[[שפת מכונה|שפות מכונה]]. הנוהג בעולם התוכנה הוא שלכל מטודהמתודה / שגרה רושמים הערות שקשורות אליה. הערות אלו אומרות למפתח מה משמעות המשתנים שנשלחים למטודהלמתודה, ותיאור קצר של אופן פעולתה.
 
[[תכנות פרוצדורלי]] הוא פרדיגמת תכנות המתבססת על שימוש בשגרות. ב[[תכנות מונחה עצמים]], לכל עצם יש מספר שגרות או פונקציות השייכות אליו, הנקראות "שיטות" או "פונקציות חברות", ופועלות על המידע [[כימוס|הכמוס]] בתוכו או בעזרתו. שיטות אלה מהוות גם [[ממשק (תכנות)|ממשק]] בין העצם לתוכנית כולה.
שורה 10:
ישנן מספר דרכים להעביר פרמטרים לשגרות. הדרך הסטנדרטית להעברת קלט אל שגרות הוא באמצעות רשימת פרמטרים (ארגומנטים) - בקריאה לשגרה מצרפים גם סדרה של [[משתנה (תכנות)|משתנים]] או קבועים. בצורה זו מתקבל תחביר דומה מאוד לכתיבה של פונקציה מתמטית: (Make(a,b, למשל.
 
העברת המשתנים עשויה להיות על ידי העברה של הערך שלהם (By Value), כלומר העתקת תוכנם אל משתנים חדשים, או על ידי התייחסות (By Reference), המהווה בפועל נתינת שם נוסף לאותו משתנה. בהעברת משתנים לפי ערך, המשתנים המקוריים שנשלחים למטודהלמתודה אינם משתנים בפועל. כלומר, למטודהלמתודה נשלחים העתקים של הערכים שלהם, ולא המשתנים עצמם בפועל. בהעברה על ידי התייחסות נשלחים למטודהלמתודה הכתובות של המשתנים ולא העתקים של הערכים שלהם. במטודהבמתודה כזו למשל שמקבלת שני משתנים ומחליפה ביניהם - השינוי יהיה ניכר גם לאחר סיום המטודההמתודה. בהעברה משתנים לפי ערך למטודהלמתודה כזאת, תתבצע רק החלפה שלהם "באוויר". המשתנים עצמם לא ישתנו בפועל, כאילו שהמטודהשהמתודה לא פעלה מעולם.
 
במקרה שמעבירים על ידי ערך (ב[[שפת C]], למשל, זו הדרך היחידה) ויש צורך לשנות את המשתנה המקורי, ניתן להשתמש בחלק מהשפות ב[[מצביע]]. המצביע מכיל את הערך המספרי של [[כתובת (זיכרון מחשב)|כתובת]] המשתנה בזיכרון המחשב, וכך ניתן לגשת ישירות לכתובת זו ולשנות את ערכו של המשתנה.
שורה 23:
עם זאת, באופן מהותי, קריאה לפונקציה מהווה "ביטוי", כלומר התייחסות לערך כלשהו, לעומת קריאה לפרוצדורה המהווה "פקודה", כלומר שינוי מצב של משתנים בדרך כלשהי. ב[[תכנות פונקציונלי]], פונקציה היא [[טיפוס נתונים]] בסיסי לכל דבר, והוא לב ליבה של השפה. בשפות פונקציונלית (בהן [[LISP]], [[Haskell]], או [[ML]]) לפונקציות, ולביטויים בכלל, אין תוצאות לוואי, בשאיפה. דבר זה מקל על הוכחת נכונות של קטע קוד, ולעתים גם על [[עיבוד מקבילי]].
 
סוג הפונקציה או המטודההמתודה הנפוצה ביותר בעולם התוכנה היא המטודההמתודה הבוליאנית. מטודהמתודה זו מבצעת בדיקה על פרמטרים שהיא מקבלת, או על נתונים אחרים שהיא מקבלת באופן עצמאי (על ידי פנייה למסד נתונים למשל), ומחזירה אמת או שקר. על פי המוסכמה מטודהמתודה כזאת תתחיל במילה Is, למשל IsValid, IsGood. כך לפי השם של המטודההמתודה יודעים גם שהיא בוליאנית, מחזירת אמת או שקר, וגם על מה בדיוק היא משיבה אמת או שקר.
 
==דוגמת קוד==
קטע קוד קצר בשפת C# ובו ממוחשות מספר קריאות למטודותלמתודות:
<source lang="csharp">
class Program
שורה 71:
}
</source>
התוכנית מגדירה אובייקט בשם MethodsClass, בעל שתי שדות מטיפוס מספר שלם. הראשון נקרא ID והשני נקרא Number. תמיד לפני שם של כל מטודהמתודה רושמים את מסנן הגישה למטודהלמתודה (ציבורי או פרטי) ואת טיפוס ההחזרה של המטודההמתודה. בסוגרים רושמים את סוגי הפרמטרים ואת השמות שלהם. כל אלו ביחד נקראים "חתימת המטודההמתודה".{{ש}}
לאובייקט זה יש 4 מטודותמתודות:
* בנאי (Constructor) שמקבל 2 פרמטרים ונקרא ()MethodsClass - אלו הערכים שייקלטו לשדות של האובייקט. הבנאי הוא מטודהמתודה מיוחדת - היא מייצרת את האובייקט עצמו, לא ניתן להגיר שתחזיר void או סוג נתונים אחר.
* מטודהמתודה שלא מחזירה ערך ()SayHello - המטודההמתודה רק מדפיסה למסך את המילים Hello World.
* מטודהמתודה שמחזירה מספר שלם ()SumOfIDandNumber - המטודההמתודה מחזירה את סכום 2 השדות שלה.
* מטודהמתודה שמקבלת כפרמטר מספר ומחזירה אמת או שקר ()IsEvenNumber - המטודההמתודה מחזירה אמת אם המספר שנשלח לה מתחלק ב-2 ללא שארית, אחר מחזירה שקר.
 
זהו הפלט של קטע הקוד הנתון:
שורה 84:
True
 
==סוגים של מטודותמתודות==
 
* מטודהמתודה [[רקורסיה|רקורסיבית]] - מטודהמתודה שמפעילה את עצמה עד להגעה לתנאי עצירה מסוים. בעזרת מטודותמתודות רקורסיביות, ניתן לממש הגדרות רקורסיביות כגון עצרת, סדרת פיבונצ'י או סדרות נסיגה. כדי לדעת למשל את ערך של !10 צריך לכפול את 10 ב-9, את התוצאה יש לכפול ב-8 וכן הלאה עד שכופלים ב-1. מטודהמתודה רקורסיבית שתממש עצרת תמשיך לקרוא לעצמה עד שהפרמטר (הכופל) של התוצאה הוא 1. כל מטודהמתודה שמפעילה לולאה על מנת להשיג תוצאה מסוימת, ניתן להמיר למטודהלמתודה רקורסיבית ולהיפך.
* מטודהמתודה וירטואלית - מטודהמתודה שמוגדרת באובייקט אב כמטודהכמתודה וירטואלית. אובייקטים שיירשו ממחלקת האב יוכלו לממש את המטודההמתודה מאובייקט האב באופן אחר (Override) וכך יתאפשר פולימורפיזם. לדוגמה, אובייקט האב הוא גיבור-על ויש לו מטודהמתודה בשם פעולת-על (SuperAction) שהיא מוגדרת כוירטואלית, ויש לה מימוש כלשהו. אובייקט שיירש תכונות מהאובייקט גיבור-על (למשל [[באטמן]]) יממש את המטודההמתודה פעולת-על באופן אחר. אובייקט שני שיירש תכונות מאובייקט האב גיבור-על (למשל [[סופרמן]]) יממש את המטודההמתודה פעולת-על באופן שלישי. לכל מופע של כל אחד משלושת האובייקטים תהיה אותה מטודהמתודה ועם אותם פרמטרים (או היעדרם) אבל עם מימוש, אופן פעולה שונה.
* מטודהמתודה אבסטרקטית - מטודהמתודה שמוגרת באובייקט אב אבסטרקטי (לא ניתן ליצור לו מופע), והאובייקטים היורשים מממשים בצורה שונה. להבדיל ממטודהממתודה וירטואלית, מטודהמתודה אבסטרקטית באובייקט האב אינה מכילה קוד.
* מטודהמתודה בוליאנית - קיימת כמעט בכל אובייקט מרכזי בתוכנה, מחזירה תשובה של אמת או שקר. לפי מוסכמה מתחילה במילה Is ובהמשך הנתון שרוצים לחקור, למשל ()IsLate(), IsTrueOrFalse.
* מטודהמתודה סטטית - מטודהמתודה שקיימת באובייקט סטטי, דהיינו אובייקט שאי אפשר ליצור לו מופע. האובייקט Math למשל ב-C# הוא אובייקט סטטי - קיים רק ייצוג יחיד שלו בזיכרון התוכנה ולא ניתן לשכפל אותו. כאשר רוצים לקבל שורש של מספר מפעילים את המטודההמתודה המתאימה של האובייקט: (Math.Sqrt(25 - יחזיר את השורש של 25, זאת מבלי לקרוא למופע של אובייקט מסוג Math.
 
לכל מטודהמתודה מכל סוג שהוא יש מסנני גישה, או שמטודהשמתודה היא ציבורית (public) או שמטודהשמתודה היא פרטית (private). מטודהמתודה ציבורית היא מטודהמתודה שניתן לפנות אליה גם מחוץ לאובייקט שבו היא מוגדרת. מטודהמתודה פרטית לעומת זאת ניתנת להפעלה רק בתוך האובייקט בו היא מוגדרת.
 
==העמסה, משתנים גלובליים ומשתנים מקומיים==
 
משתנה גלובלי הוא משתנה שמוכר לכל המטודותהמתודות באובייקט. לא ניתן להגדיר בתוך מטודהמתודה משתנה עם אותו שם כמו של המשתנה הגלובלי. משתנה מקומי הוא משתנה שמוגדר רק באזור העבודה של המטודההמתודה (בין הסוגריים המסולסלים בסי שארפ לדוגמה). לא ניתן לפנות למשתנה מקומי של מטודהמתודה אחת מתוך מטודהמתודה אחרת, כי עם סיום המטודההמתודה האובייקט המקומי מושמד (מנוקה על ידי מנגנון [[איסוף זבל|איסוף הזבל]] עבור קוד מנוהל).
בדוגמה הבאה המשתנה Global הוא משתנה גלובלי, כל מטודהמתודה יכולה לגשת ולשנות את המידע שלו. לעומת זאת, לכל מטודהמתודה יש משתנה מקומי משלה שהוא מוכר רק בתוך כל מטודהמתודה. לא ניתן לפנות למשתנה הזה ממקום אחר בתוכנית. המטודההמתודה השנייה לא יכולה לגשת ל-Local1 והמטודהוהמתודה הראשונה לא יכולה לגשת למשתנה Local2. אף אחת מהן לא יכולה להגדיר משתנה בשם Global כי משתנה שכזה כבר קיים ומוכר לכל.
 
העמסה - קריאה למספר מטודותמתודות של אובייקט תחת אותו שם אבל עם חתימה שונה (מספר ו/או כמות שונה של פרמטרים). בדוגמה הבאה ישנם שלוש מטודותמתודות בשם OverLoad, הראשונה מקבלת רק מספר שלם, השנייה מקבלת מספר שלם ומספר עשרוני, והשלישית מקבלת מילה, מספר שלם ואמת או שקר (משתנה בוליאני). המשתנה האחרון של המטודההמתודה השלישית מוגדר להיות כברירת מחדל אמת. תמיד משתנים דיפולטיים מוגדרים בסוף המטודההמתודה, כי יכולים להיות למטודהלמתודה מספר פרמטרים מאותו סוג. אם למשל היו מוגדרים למטודהלמתודה 3 פרמטרים מטיפוס בוליאני, כאשר הפרמטר השני היה דיפולטי ובנוסף הייתה קיימת עוד מטודהמתודה עם 2 פרמטרים בוליאניים - הדבר היה יוצר התנגשות כאשר היו מפעילים את המטודההמתודה רק עם 2 פרמטרים. המשתמש יכול להחליט שהוא מפעיל מטודהמתודה זאת מבלי לציין אמת או שקר בקריאה למטודהלמתודה. רק אם הוא רוצה שהמטודהשהמתודה תפעל עם משתנה אחרון עם ערך של שקר הוא צריך לשלוח שקר. לפי סוג הפרמטרים שנשלחים למטודהלמתודה והכמות שלהם - התוכנית יודעת לאיזה מטודהמתודה לגשת ולפיכך איזה קטע קוד (מטודהמתודה) להפעיל.
 
בדוגמה מוצגות מטודותמתודות פרטיות, כלומר רק האובייקט Program יכול לגשת אליהם ולהפעיל אותם. אם קובץ אחר היה מנסה לגשת למטודותלמתודות לא הייתה לו אפשרות לעשות זאת. כמו כן, מאחר ו-Console הוא סטטי, כל מטודהמתודה שבו חייבת להיות סטטית. זאת הסיבה שכל מטודהמתודה פותחת במילה static, וכן במילה Private.
 
<source lang="csharp">