קריאה למצביעים לפונקציות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 34 מתוך 61.
כעת, לאחר שלמדת איך להצהיר על מצביע לפונקציה ולהקצות לו פונקציה, השלב הבא הוא למעשה לקרוא לפונקציה דרך המצביע הזה.
התחביר פשוט. משתמשים במצביע לפונקציה בדיוק כפי שהייתם קוראים לפונקציה רגילה:
int add(int a, int b) {
return a + b;
}
int main() {
int (*operation)(int, int) = add;
int result = operation(5, 3); // קורא ל-add(5, 3)
printf("%d\n", result); // פלט: 8
return 0;
}פשוט כתבו את שם המצביע ואחריו סוגריים המכילים את הארגומנטים. C מבצעת באופן אוטומטי ביטול הפניה למצביע ומריצה את הפונקציה שעליה הוא מצביע.
אפשר גם להשתמש בתחביר מפורש של הסרת הפניה בעזרת (*operation)(5, 3), אבל זה אופציונלי ופחות נפוץ. שתי הצורות מניבות תוצאות זהות.
העוצמה האמיתית מתגלה כשמקצים מחדש את המצביע לפונקציות שונות:
int subtract(int a, int b) {
return a - b;
}
operation = subtract;
result = operation(5, 3); // כעת קורא ל־subtract(5, 3)
printf("%d\n", result); // פלט: 2אותו משתנה operation מבצע עכשיו לוגיקה שונה לחלוטין. היכולת הזאת להחליף התנהגות בזמן ריצה היא הבסיס לפולימורפיזם ב-C.
אתגר
קלבואו נתרגל קריאה לפונקציות באמצעות מצביעים והחלפה של הפונקציה שמתבצעת. תבנו מחשבון פשוט שיכול לעבור בין חיבור לחיסור בזמן ריצה.
כתבו תוכנית ש:
- מגדירה שתי פונקציות:
add: מקבלת שני פרמטרים מסוגintומחזירה את הסכום שלהםsubtract: מקבלת שני פרמטרים מסוגintומחזירה את הראשון פחות השני
- בתוך
main, מצהירה על מצביע לפונקציה בשםcalcשיכול להצביע לפונקציות המקבלות שני פרמטרים מסוגintומחזירותint - קוראת ארבעה נתונים: שני מספרים שלמים ושני קודי פעולה
- עבור כל קוד פעולה:
- מקצה את הפונקציה המתאימה ל-
calc(1 עבור add, 2 עבור subtract) - קוראת לפונקציה באמצעות המצביע עם שני המספרים
- מדפיסה את התוצאה
- מקצה את הפונקציה המתאימה ל-
תקבלו ארבעה נתונים: המספר הראשון, המספר השני, קוד הפעולה הראשון (1 או 2), וקוד הפעולה השני (1 או 2).
הפלט שלכם צריך להציג שתי תוצאות בשורות נפרדות: אחת עבור כל פעולה שבוצעה באמצעות אותם שני מספרים:
15
5בדוגמה זו, עם הקלטים 10, 5, 1, 2: הפעולה הראשונה (קוד 1) מחברת 10 + 5 = 15, לאחר מכן המצביע מוקצה מחדש, והפעולה השנייה (קוד 2) מחסרת 10 - 5 = 5.
כך מודגם כיצד אותו משתנה מצביע יכול לבצע לוגיקה שונה לחלוטין על ידי הקצאה מחדש שלו בין קריאות.
נסו בעצמכם
#include <stdio.h>
// TODO: הגדירו כאן את הפונקציה add
// TODO: הגדירו כאן את הפונקציה subtract
int main() {
// קראו את הקלט
int num1, num2, op1, op2;
scanf("%d", &num1);
scanf("%d", &num2);
scanf("%d", &op1);
scanf("%d", &op2);
// TODO: הכריזו על מצביע לפונקציה בשם 'calc' שיכול להצביע על
// פונקציות שמקבלות שני פרמטרים מסוג int ומחזירות ערך מסוג int
// TODO: עבור קוד הפעולה הראשון (op1):
// - הקצו ל-calc את הפונקציה המתאימה (1 עבור add, 2 עבור subtract)
// - קראו לפונקציה באמצעות המצביע והדפיסו את התוצאה
// TODO: עבור קוד הפעולה השני (op2):
// - הקצו מחדש ל-calc את הפונקציה המתאימה
// - קראו לפונקציה באמצעות המצביע והדפיסו את התוצאה
return 0;
}השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית7מצביעים לפונקציות
הצהרת מצביעים לפונקציותקריאה למצביעים לפונקציותשימוש ב-typedef עבור מצביעים לפונקציותהעברת פונקציות כארגומנטיםסיכום: ניתוב במחשבון2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין