Menu
Coddy logo textTech

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 das Objekt selbst automatisch an die Methode, wenn man object.method() aufruft. In C müssen wir dies manuell tun, indem wir einen Zeiger auf das Struct als erstes Argument übergeben.

Dieser Zeiger wird üblicherweise self (aus Python übernommen) oder this (aus C++) genannt. Er gibt der Funktion Zugriff auf die Daten des Structs, 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-Pointer lässt die Funktion wie eine Methode agieren – er weiß, welchen Spieler er modifizieren soll. Ohne ihn hätte die Funktion keine Möglichkeit, auf die spezifische Struct-Instanz zuzugreifen. Beim Aufrufen dieser Funktion übergibst du die Adresse deines Structs:

Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ist jetzt 75

Die Verwendung eines Pointers (anstatt das Struct direkt zu übergeben) ist für Modifikationen unerlässlich. Wenn Sie das Struct per Wert (by value) übergeben würden, würde die Funktion eine Kopie erhalten, und alle Änderungen gingen verloren, wenn die Funktion zurückkehrt. Der Pointer stellt sicher, dass Änderungen im ursprünglichen Struct erhalten bleiben.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Timer-Modul bauen, das die verstrichenen Sekunden verfolgt. Sie werden üben, das "self"-Pointer-Muster zu verwenden, um den internen Zustand eines Structs durch Funktionen zu ändern, die wie Methoden agieren.

Sie werden drei Dateien erstellen:

  • timer.h: Deklarieren Sie ein Timer-Struct mit einem einzelnen int seconds-Member. Deklarieren Sie außerdem zwei Funktionen: timer_tick (nimmt einen Zeiger auf Timer entgegen und addiert eine bestimmte Anzahl von Sekunden) und timer_reset (nimmt einen Zeiger auf Timer entgegen und setzt die Sekunden zurück auf Null). Verwenden Sie Include-Guards mit dem Symbol TIMER_H.
  • timer.c: Implementieren Sie beide Funktionen. Die Funktion timer_tick sollte einen Timer *self und ein int amount akzeptieren und dann den Betrag zu den Sekunden des Timers addieren. Die Funktion timer_reset sollte einen Timer *self akzeptieren und dessen Sekunden auf Null setzen.
  • main.c: Erstellen Sie einen Timer, führen Sie Operationen damit aus und zeigen Sie die Ergebnisse an.

Sie erhalten zwei Ganzzahl-Eingaben: die initial seconds für Ihren Timer und den amount to add via Tick.

In Ihrer Hauptdatei:

  1. Initialisieren Sie einen Timer mit dem Wert der initialen Sekunden
  2. Rufen Sie timer_tick auf, um den angegebenen Betrag hinzuzufügen
  3. Geben Sie die aktuellen Sekunden aus
  4. Rufen Sie timer_reset auf, um den Timer zurückzusetzen
  5. Geben Sie die Sekunden erneut aus (sollte 0 sein)

Geben Sie die Ergebnisse in diesem Format aus:

After tick: {seconds}
After reset: {seconds}

Zum Beispiel, bei einem Initialwert von 30 und dem Hinzufügen von 15 Sekunden, wäre die Ausgabe:

After tick: 45
After reset: 0

Spickzettel

In C benötigen Funktionen, die auf Structs operieren, expliziten Zugriff auf die Struct-Instanz über einen Zeiger-Parameter, der konventionell self oder this genannt wird:

typedef struct {
    int health;
} Player;

void player_take_damage(Player *self, int amount) {
    self->health -= amount;
}

Der self-Zeiger ermöglicht es der Funktion, auf die Daten des Structs zuzugreifen und diese zu ändern. Wenn Sie solche Funktionen aufrufen, übergeben Sie die Adresse Ihres Structs:

Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ist jetzt 75

Die Verwendung eines Zeigers ist für Änderungen unerlässlich – die Übergabe als Wert (pass by value) würde eine Kopie erstellen, und Änderungen gingen verloren, wenn die Funktion zurückkehrt. Der Zeiger stellt sicher, dass Änderungen im ursprünglichen Struct erhalten bleiben.

Probier 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: Erstellen Sie einen Timer und initialisieren Sie ihn mit initial_seconds
    
    // TODO: Rufen Sie timer_tick auf, um amount_to_add Sekunden hinzuzufügen
    
    // TODO: Geben Sie die aktuellen Sekunden im Format "After tick: {seconds}" aus
    
    // TODO: Rufen Sie timer_reset auf, um den Timer zurückzusetzen
    
    // TODO: Geben Sie die Sekunden erneut im Format "After reset: {seconds}" aus
    
    return 0;
}
quiz iconTeste dich selbst

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