Der 'Self'-Pointer
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 7 von 61.
In objektorientierten Sprachen wie Python oder Java übergibt die Sprache das Objekt selbst automatisch an die Methode, wenn du object.method() aufrufst. In C müssen wir dies manuell tun, indem wir einen Zeiger auf die Struktur als erstes Argument übergeben.
Dieser Zeiger wird üblicherweise self (aus Python übernommen) oder this (aus C++) genannt. Er ermöglicht der Funktion den Zugriff auf die Daten der Struktur, 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 Funktion wie eine Methode verhält. Er weiß, welchen Spieler er ändern soll. Ohne ihn hätte die Funktion keine Möglichkeit, auf die jeweilige Strukturinstanz zuzugreifen. Beim Aufrufen dieser Funktion übergibst du die Adresse deiner Struktur:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ist jetzt 75
Die Verwendung eines Zeigers (anstatt die Struktur direkt zu übergeben) ist für Änderungen unerlässlich. Wenn du die Struktur als Wert übergeben würdest, würde die Funktion eine Kopie erhalten, und alle Änderungen wären verloren, sobald die Funktion zurückkehrt. Der Zeiger stellt sicher, dass die Änderungen in der ursprünglichen Struktur erhalten bleiben.
Aufgabe
EinfachErstelle ein Timer-Modul, das die verstrichenen Sekunden verfolgt. Du übst dabei das Muster mit dem „self“-Zeiger, um den internen Zustand einer Struktur durch Funktionen zu verändern, die als Methoden fungieren.
Du erstellst drei Dateien:
timer.h: Deklariere eineTimer-Struktur mit einem einzigen Elementint seconds. Deklariere außerdem zwei Funktionen:timer_tick(nimmt einen Zeiger auf einen Timer entgegen und addiert eine bestimmte Anzahl von Sekunden) undtimer_reset(nimmt einen Zeiger auf einen Timer entgegen und setzt seconds wieder auf null). Verwende Include-Guards mit dem SymbolTIMER_H.timer.c: Implementiere beide Funktionen. Die Funktiontimer_ticksoll einenTimer *selfund einint amountentgegennehmen und anschließend den Betrag zu den Sekunden des Timers addieren. Die Funktiontimer_resetsoll einenTimer *selfentgegennehmen und dessen seconds auf null setzen.main.c: Erstelle einen Timer, führe Operationen darauf aus und gib die Ergebnisse aus.
Du erhältst zwei ganzzahlige Eingaben: die initialen Sekunden für deinen Timer und den zu addierenden Betrag über tick.
In deiner Hauptdatei:
- Initialisiere einen
Timermit dem Wert der initialen Sekunden - Rufe
timer_tickauf, um den angegebenen Betrag zu addieren - Gib die aktuellen Sekunden aus
- Rufe
timer_resetauf, um den Timer zurückzusetzen - Gib die Sekunden erneut aus (sollte 0 sein)
Gib die Ergebnisse in diesem Format aus:
After tick: {seconds}
After reset: {seconds}Wenn der Anfangswert beispielsweise 30 beträgt und 15 Sekunden addiert werden, würde die Ausgabe folgendermaßen aussehen:
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 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