נכונות const
חלק מהיחידה תכנות מונחה עצמים במסלול ה-C של Coddy. שיעור 8 מתוך 61.
כשכותבים פונקציות שפועלות כמתודות, חלקן צריכות לשנות את האובייקט (כמו player_take_damage), ואחרות צריכות רק לקרוא נתונים בלי לשנות דבר. מילת המפתח const מאפשרת לאכוף את ההבחנה הזאת ברמת המהדר.
כשמסמנים פרמטר מצביע בתור const, מתחייבים שהפונקציה לא תשנה את הנתונים שאליהם הוא מצביע. אם תנסה בטעות לשנות איבר, המהדר יציג שגיאה:
typedef struct {
int x;
int y;
} Point;
// הפונקציה הזו יכולה רק לקרוא את הנקודה
void point_print(const Point *self) {
printf("(%d, %d)\n", self->x, self->y);
// self->x = 10; // שגיאה: אי אפשר לשנות דרך מצביע const
}
// הפונקציה הזו יכולה לשנות את הנקודה
void point_move(Point *self, int dx, int dy) {
self->x += dx;
self->y += dy;
}
הפרמטר const Point *self מציין הן למהדר והן למתכנתים אחרים ש־point_print היא פעולת "getter" או פעולה לקריאה בלבד. הדבר נקרא נכונות const: שימוש ב־const בכל מקום שבו אין צורך בשינוי.
התרגול הזה עוזר לזהות באגים מוקדם. אם תכתוב פונקציית תצוגה ותשנה בטעות שדה, המהדר יעצור אותך מיד במקום לאפשר לבאג להיכנס לתוכנית שלך.
אתגר
קלנבנה מודול Temperature ששומר ערך של טמפרטורה ומספק פעולות לקריאה בלבד ולשינוי. כך תוכל להתאמן בשימוש במצביעי const כדי להבחין בבירור בין פונקציות שרק קוראות נתונים לבין פונקציות שמשנות אותם.
תיצור שלושה קבצים:
temperature.h: הכרז על מבנהTemperatureעם איבר יחיד מסוגdouble celsius. הכרז גם על שלוש פונקציות:temp_display: מקבלת מצביעconstל-Temperature ומדפיסה את הטמפרטורה הנוכחית (לקריאה בלבד)temp_adjust: מקבלת מצביע רגיל ל-Temperature וכמות מסוג double, ואז מוסיפה את הכמות ל-celsius (לשינוי)temp_to_fahrenheit: מקבלת מצביעconstל-Temperature ומחזירה את הערך כשהוא מומר לפרנהייט (לקריאה בלבד)
TEMPERATURE_H.temperature.c: ממש את כל שלוש הפונקציות. הפונקציהtemp_displayצריכה להדפיס בפורמטCurrent: {celsius}C. הפונקציהtemp_to_fahrenheitצריכה להחזיר את הערךcelsius * 9.0 / 5.0 + 32.0. זכור שפונקציות שמשתמשות במצביעיconstאינן יכולות לשנות את נתוני המבנה.main.c: צור Temperature, בצע פעולות והצג את התוצאות.
תקבל שני קלטים: ערך הצלזיוס ההתחלתי (מסוג double) וכמות ההתאמה (מסוג double).
בקובץ הראשי שלך:
- אתחל
Temperatureעם ערך הצלזיוס ההתחלתי - קרא ל-
temp_displayכדי להציג את הטמפרטורה ההתחלתית - קרא ל-
temp_adjustכדי לשנות את הטמפרטורה לפי כמות ההתאמה - קרא שוב ל-
temp_displayכדי להציג את הטמפרטורה המעודכנת - הדפס את ההמרה לפרנהייט באמצעות
temp_to_fahrenheit
הדפס את התוצאות בפורמט הזה:
Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}Fהשתמש ב-%.1f לכל ערכי הטמפרטורה כדי להציג ספרה אחת אחרי הנקודה העשרונית.
לדוגמה, עם ערך התחלתי של 20.0 והתאמה של 5.0, הפלט יהיה:
Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0Fנסו בעצמכם
#include <stdio.h>
#include "temperature.h"
int main() {
double initial_celsius, adjustment;
scanf("%lf", &initial_celsius);
scanf("%lf", &adjustment);
// TODO: צור מבנה Temperature ואתחל אותו עם initial_celsius
// TODO: קרא ל-temp_display כדי להציג את הטמפרטורה ההתחלתית
// TODO: קרא ל-temp_adjust כדי לשנות את הטמפרטורה בכמות adjustment
// TODO: קרא שוב ל-temp_display כדי להציג את הטמפרטורה המעודכנת
// TODO: הדפס את ההמרה לפרנהייט באמצעות temp_to_fahrenheit
// פורמט: "Fahrenheit: %.1fF\n"
return 0;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4כימוס
המושג של מצביעים אטומיםהגדרת מבנים אטומיםפונקציות Get ו-Setאימות ב-Settersסיכום: הקופסה הסודית2אובייקטים ומתודות
מבנים כאובייקטיםמצביע 'Self'נכונות constמצביע לעומת ערךמתודות עזרחזרה: מנהל נקודות5פרויקט: חשבון בנק פשוט
הגדרת הפרויקטמימוש החשבוןתרגלו בעצמכם: קומפיילר C אונליין