Der 'Self'-Pointer
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy. Lektion 7 von 61.
In objektorientierten Sprachen wie Python oder Java übergibt die Sprache dem method beim Aufruf von object.method() automatisch das Objekt selbst. In C müssen wir dies manuell tun, indem wir einen pointer auf das struct als erstes Argument übergeben.
Dieser Zeiger wird konventionell self (aus Python übernommen) oder this (aus C++) genannt. Er ermöglicht der Funktion den Zugriff auf die Daten von struct, sodass sie diese lesen oder ändern kann:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
Der self-Zeiger sorgt dafür, dass sich die function wie eine Methode verhält. Er weiß, welcher player geändert werden soll. Ohne ihn hätte die function keine Möglichkeit, auf die spezifische struct-Instanz zuzugreifen. Beim Aufrufen dieser function übergibst du die Adresse deiner struct:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ist jetzt 75
Die Verwendung eines pointer (anstatt die struct direkt zu übergeben) ist für Änderungen unerlässlich. Wenn du die struct per Wert übergeben würdest, würde die function eine Kopie erhalten, und alle Änderungen gingen verloren, wenn die function zurückkehrt. Der pointer stellt sicher, dass die Änderungen in der ursprünglichen struct erhalten bleiben.
Aufgabe
EinfachLass uns ein Timer-Modul erstellen, das vergangene seconds verfolgt. Du wirst üben, das „self“-pointer-Muster zu verwenden, um den internen Zustand eines struct über Funktionen zu ändern, die als Methoden fungieren.
Du wirst drei Dateien erstellen:
timer.h: Deklariere einTimer-struct mit einem einzigenint seconds-member. Deklariere außerdem zwei Funktionen:timer_tick(takes einen pointer auf Timer und adds eine angegebene Anzahl von seconds) undtimer_reset(takes einen pointer auf Timer und setzt seconds auf zero zurück). Verwende include guards mit dem SymbolTIMER_H.timer.c: Implementiere beide Funktionen. Die Funktiontimer_ticksollte einenTimer *selfund einint amountaccept, dann amount zu den seconds des timers add. Die Funktiontimer_resetsollte einenTimer *selfaccept und dessen seconds auf zero setzen.main.c: Erstelle einen Timer, führe Operationen daran aus und zeige die Ergebnisse an.
Du erhältst zwei integer inputs: die initial seconds für deinen timer und den amount to add über tick.
In deiner main-Datei:
- Initialisiere einen
Timermit dem Wert für initial seconds - Rufe
timer_tickauf, um den angegebenen amount zu add - Gib die aktuellen seconds aus
- Rufe
timer_resetauf, um den timer zurückzusetzen - Gib die seconds erneut aus (should 0 sein)
Gib die Ergebnisse in diesem format aus:
After tick: {seconds}
After reset: {seconds}Wenn der initial value beispielsweise 30 beträgt und 15 seconds hinzugefügt werden, wäre die Ausgabe:
After tick: 45
After reset: 0Probier es selbst
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: Erstelle einen Timer und initialisiere ihn mit initial_seconds
// TODO: Rufe timer_tick auf, um amount_to_add Sekunden hinzuzufügen
// TODO: Gib die aktuellen Sekunden im Format aus: "After tick: {seconds}"
// TODO: Rufe timer_reset auf, um den Timer zurückzusetzen
// TODO: Gib die Sekunden erneut im Format aus: "After reset: {seconds}"
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Object Oriented Programming
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