מצביע 'Self'
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 7 מתוך 61.
בשפות מונחות עצמים כמו Python או Java, כשקוראים ל־object.method(), השפה מעבירה אוטומטית את האובייקט עצמו לפונקציה. ב־C, עלינו לעשות זאת ידנית על ידי העברת מצביע למבנה כארגומנט הראשון.
המצביע הזה נקרא בדרך כלל self (בהשאלה מ-Python) או this (מ-C++). הוא מאפשר לפונקציה לגשת לנתונים של המבנה, כדי שתוכל לקרוא אותם או לשנות אותם:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
המצביע self הוא זה שגורם לפונקציה לפעול כמו מתודה. הוא יודע איזה שחקן לשנות. בלעדיו, לפונקציה לא הייתה דרך לגשת למופע הספציפי של המבנה. כשקוראים לפונקציה הזאת, מעבירים אליה את הכתובת של המבנה שלך:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health הוא כעת 75
השימוש במצביע (במקום להעביר את המבנה ישירות) חיוני כדי לשנות אותו. אם היית מעביר את המבנה לפי ערך, הפונקציה הייתה מקבלת עותק, וכל שינוי היה אובד כשהפונקציה הייתה מסתיימת. המצביע מבטיח שהשינויים יישמרו במבנה המקורי.
אתגר
קלבואו נבנה מודול Timer שעוקב אחר מספר השניות שחלפו. תתרגלו שימוש בתבנית המצביע "self" כדי לשנות את המצב הפנימי של מבנה באמצעות פונקציות שפועלות כמו מתודות.
תיצרו שלושה קבצים:
timer.h: הכריזו על מבנהTimerעם איבר יחיד מסוגint seconds. הכריזו גם על שתי פונקציות:timer_tick(מקבלת מצביע ל-Timer ומוסיפה מספר מוגדר של שניות) ו-timer_reset(מקבלת מצביע ל-Timer ומחזירה את מספר השניות לאפס). השתמשו בשומרי הכללה עם הסמלTIMER_H.timer.c: ממשו את שתי הפונקציות. הפונקציהtimer_tickצריכה לקבלTimer *selfו-int amount, ואז להוסיף את הכמות למספר השניות של הטיימר. הפונקציהtimer_resetצריכה לקבלTimer *selfולאפס את מספר השניות שלו.main.c: צרו Timer, בצעו עליו פעולות והציגו את התוצאות.
תקבלו שני מספרים שלמים כקלט: מספר השניות ההתחלתי של הטיימר שלכם והכמות להוספה באמצעות tick.
בקובץ הראשי שלכם:
- אתחלו
Timerעם ערך השניות ההתחלתי - קראו ל-
timer_tickכדי להוסיף את הכמות שצוינה - הדפיסו את מספר השניות הנוכחי
- קראו ל-
timer_resetכדי לאפס את הטיימר - הדפיסו שוב את מספר השניות (הוא אמור להיות 0)
הדפיסו את התוצאות בפורמט הזה:
After tick: {seconds}
After reset: {seconds}לדוגמה, אם הערך ההתחלתי הוא 30 ומוסיפים 15 שניות, הפלט יהיה:
After tick: 45
After reset: 0נסו בעצמכם
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: צור Timer ואתחל אותו עם initial_seconds
// TODO: קרא ל-timer_tick כדי להוסיף amount_to_add שניות
// TODO: הדפס את מספר השניות הנוכחי בפורמט: "After tick: {seconds}"
// TODO: קרא ל-timer_reset כדי לאפס את הטיימר
// TODO: הדפס שוב את מספר השניות בפורמט: "After reset: {seconds}"
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין