Const-Correctness
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 8 von 61.
Beim Schreiben von Funktionen, die als Methoden fungieren, sollten einige das Objekt ändern (wie player_take_damage), während andere Daten nur lesen sollten, ohne etwas zu ändern. Mit dem Schlüsselwort const kannst du diese Unterscheidung auf Compilerebene durchsetzen.
Indem du einen Zeigerparameter als const kennzeichnest, versprichst du, dass die Funktion die Daten, auf die er zeigt, nicht verändert. Wenn du versehentlich versuchst, ein Element zu ändern, gibt der Compiler einen Fehler aus:
typedef struct {
int x;
int y;
} Point;
// Diese Funktion kann den Punkt nur LESEN
void point_print(const Point *self) {
printf("(%d, %d)\n", self->x, self->y);
// self->x = 10; // ERROR: kann nicht über const-Zeiger geändert werden
}
// Diese Funktion kann den Punkt ÄNDERN
void point_move(Point *self, int dx, int dy) {
self->x += dx;
self->y += dy;
}
Der Parameter const Point *self teilt sowohl dem Compiler als auch anderen Programmierern mit, dass point_print eine „Getter“- oder schreibgeschützte Operation ist. Dies wird als Const-Korrektheit bezeichnet: const überall dort zu verwenden, wo keine Änderung erforderlich ist.
Diese Übung erkennt Fehler frühzeitig. Wenn du eine Anzeigefunktion schreibst und versehentlich ein Feld änderst, stoppt der Compiler dich sofort, anstatt den Fehler unbemerkt in dein Programm gelangen zu lassen.
Aufgabe
EinfachErstellen wir ein Temperature-Modul, das einen Temperaturwert speichert und sowohl schreibgeschützte als auch ändernde Operationen bereitstellt. So kannst du üben, const-Zeiger zu verwenden, um klar zwischen Funktionen zu unterscheiden, die Daten nur lesen, und solchen, die sie ändern.
Du erstellst drei Dateien:
temperature.h: Deklariere eineTemperature-Struktur mit einem einzigendouble celsius-Member. Deklariere außerdem drei Funktionen:temp_display: nimmt einenconst-Zeiger auf Temperature entgegen und gibt die aktuelle Temperatur aus (schreibgeschützt)temp_adjust: nimmt einen regulären Zeiger auf Temperature und einen double-Wert entgegen und addiert den Wert zu celsius (ändernd)temp_to_fahrenheit: nimmt einenconst-Zeiger auf Temperature entgegen und gibt den in Fahrenheit umgerechneten Wert zurück (schreibgeschützt)
TEMPERATURE_H.temperature.c: Implementiere alle drei Funktionen. Die Funktiontemp_displaysoll im FormatCurrent: {celsius}Causgeben. Die Funktiontemp_to_fahrenheitsollcelsius * 9.0 / 5.0 + 32.0zurückgeben. Denke daran, dass Funktionen, dieconst-Zeiger verwenden, die Daten der Struktur nicht ändern können.main.c: Erstelle ein Temperature, führe Operationen aus und gib die Ergebnisse aus.
Du erhältst zwei Eingaben: den anfänglichen Celsius-Wert (als double) und den Anpassungsbetrag (als double).
In deiner Hauptdatei:
- Initialisiere ein
Temperaturemit dem anfänglichen Celsius-Wert - Rufe
temp_displayauf, um die Anfangstemperatur anzuzeigen - Rufe
temp_adjustauf, um die Temperatur um den Anpassungsbetrag zu ändern - Rufe
temp_displayerneut auf, um die aktualisierte Temperatur anzuzeigen - Gib die Fahrenheit-Umrechnung mit
temp_to_fahrenheitaus
Gib die Ergebnisse in diesem Format aus:
Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}FVerwende %.1f für alle Temperaturwerte, um eine Dezimalstelle anzuzeigen.
Wenn der Anfangswert beispielsweise 20.0 und die Anpassung 5.0 beträgt, wäre die Ausgabe:
Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0FProbier es selbst
#include <stdio.h>
#include "temperature.h"
int main() {
double initial_celsius, adjustment;
scanf("%lf", &initial_celsius);
scanf("%lf", &adjustment);
// TODO: Erstelle eine Temperature-Struktur und initialisiere sie mit initial_celsius
// TODO: Rufe temp_display auf, um die Starttemperatur anzuzeigen
// TODO: Rufe temp_adjust auf, um die Temperatur um den Anpassungsbetrag zu ändern
// TODO: Rufe temp_display erneut auf, um die aktualisierte Temperatur anzuzeigen
// TODO: Gib die Fahrenheit-Umwandlung mit temp_to_fahrenheit aus
// Format: "Fahrenheit: %.1fF\n"
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-ContainerÜbe selbstständig: Online-C-Compiler