23-01-2010, 13:17
|
|
|
חבר מתאריך: 30.07.05
הודעות: 949
|
|
פונקציה היא בסה"כ קטע קוד.
קטע הקוד הזה, בתהליך הקומפילציה הופך לשפת מכונה ונכתב במקום כלשהו בתוך קובץ ההפעלה (EXE) שנוצר.
כאשר את מפעילה קובץ EXE, הקוד שמוכל בתוכו נטען לזיכרון של המחשב ומשם הוא מורץ.
כאשר את קוראת לפונקציה בקוד שלך, למעשה (בצורה מאד מאד מופשטת) את אומרת למעבד שלך להמשיך לקרוא את התוכנית ממקום אחר - המקום בו רשומה הפונקציה שלך.
לכן, כמו שניתן להגדיר מצביע למקום בזיכרון ששומר מידע (int, double, מחרוזת...), ניתן להגדיר גם מבציע למקום בזיכרון בו רשומה פונקציה. זה למעשה מצביע לפונקציה.
מצביעים לפונקציות שימושיים מאד ב-C כאשר עובדים עם טיפוסי נתונים מופשטים (ADT).
למשל את רוצה ליצור טיפוס של רשימה מקושרת. במקרה כזה יש לך 2 אפשרויות:
א) להעתיק את הקוד שלך הרבה פעמים עם שינויים קטנים, וליצור רשימה מקושרת שיכולה להכיל int, רשימה שיכולה להכיל double, רשימה שיכולה להכיל.........
ב) ליצור רשימה חסרת טיפוס - כזו שמחזיקה בכלל *void, כלומר מצביע למקום בזיכרון בלי ידע מקדים על הטיפוס שלו, ובעצם לשלוח לרשימה שלך את הפונקציות המתאימות לטיפול באיברים:
פונקציה שיוצרת עותק איבר (לצורך הכנסה)
פונקציה שמשחררת את זיכרון האיבר (לצורך הוצאה)
פונקציה שמשווה בין 2 איברים (לצורך חיפוש)
ועוד פונקציות שימושיות כאלו...
כאשר תוסיפי איבר לרשימה, למשל, תשתמשי בפונקצית ההעתקה ע"מ ליצור עותק של האיבר המקורי שקיבלת לתוך פונקצית ההוספה, ותזיני את הכתובת של מה שנוצר לתוך הרשימה.
לדוגמא יש לך רשימה כזו, ואת רוצה לעבוד עם int, אז את תיצרי 3 פונקציות:
קוד PHP:
// List element type typedef void* Element; // Copy function type: receive an element and allocate a copy of it typedef Element (*CopyFunction)(Element source); // Free function type: receive an element and free it's memory typedef void (*FreeFunction)(Element elem); // Compare function type: given two elements return true if elements are equal or false otherwise typedef bool (*CompareFunction)(Element e1, Element e2);
/* ##### Integer list functions ##### */
Element IntCopy(Element source) { int *src = (int *)source; int *copy = (int *)malloc(sizeof(int)); if (copy != NULL) { *copy = *src; } return (Element)copy; }
void IntFree(Element elem) { int *src = (int *)elem; free(src); }
bool IntCompare(Element e1, Element e2) { int *src1 = (int *)e1; int *src2 = (int *)e2; return (*src1 == *src2); }
את הפונקציות הללו, את תשלחי לפונקציה שמאתחלת את הרשימה ותשמרי אותן כחלק ממבנה הרשימה, ותוכלי להשתמש בהן בפונקציות שמטפלות ברשימה.
דוגמא נוספת, אולי אפילו מובנת יותר היא פונקצית מיון!
נניח שאת רוצה למיין מערך ואת כותבת פונקציית מיון - את תאלצי לכתוב פונקציה למיון של מערך של int ופונקציה למיון של מערך של double ובעיקר פונקציה למיון של מערך מחרוזות - כל אחת בנפרד שכן לכל אחת צריך השוואה שונה!
במקום זאת, ניתן לכתוב פונקציית מיון גנרית - שתקבל מערך מטיפוס גנרי ופונקציית השוואה שבעזרתה הוא ימיין את הנתונים ממש:
קוד PHP:
// A comparison function type: // Returns -1 if e2 > e1 // Returns 0 if e1 == e2 // Returns 1 if e1 > e2 typedef int (*ComparingFunction)(void *e1, void *e2);
// The sorting function void Sort(void *Array[], ComparingFunction cmp);
// Usage: char *Text[] = { "Hello", "My", "Name", "Is", "Agent", "Smith" };
int MyStrcmp(void *e1, void *e2) { char *s1 = (char*)e1; char *s2 = (char*)e2; return strcmp(s1, s2); }
Sort(Text, MyStrcmp);
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.
נערך לאחרונה ע"י Dark Knight בתאריך 23-01-2010 בשעה 13:29.
|