Zugriff auf Parent-Member
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 30 von 61.
Nachdem wir nun das Struct-Embedding und die First-Member-Regel verstehen, konzentrieren wir uns auf die praktische Seite: wie man die Daten des eingebetteten Elternelements aus einer Funktion heraus liest und ändert.
Wenn eine Funktion ein Child Struct (oder einen Pointer darauf) erhält, erfordert der Zugriff auf die Member des Parents das Navigieren durch das eingebettete Struct. Die Syntax hängt davon ab, ob Sie mit einem Wert oder einem Pointer arbeiten.
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;Verwenden Sie bei einem Pointer auf Child den Pfeil-Operator, um das Parent-Element zu erreichen, und dann den Punkt, um auf dessen Member zuzugreifen:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Pfeil, dann Punkt
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Bei einem Wert (per Kopie übergeben) verwenden Sie durchgehend Punkte:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Punkt, dann Punkt
}Dieses verkettete Zugriffsmuster — child->parent.member oder child.parent.member — ist die Art und Weise, wie Sie mit geerbten Daten im Kompositionsmodell von C interagieren. Es ist etwas wortreicher als echte Vererbung, aber es ist explizit und klar in Bezug auf die Beziehung zwischen den Typen.
Aufgabe
EinfachLassen Sie uns ein Studenten-Bewertungssystem erstellen, das zeigt, wie man auf Daten innerhalb einer eingebetteten Struktur zugreift und diese ändert. Sie werden eine Hierarchie erstellen, in der ein Student eine eingebettete Person enthält, und dann Funktionen schreiben, die mit den Daten des Elternteils über das Kind arbeiten.
Sie werden Ihren Code auf drei Dateien verteilen:
student.h: Definieren Sie Ihre Struktur-Hierarchie mit Include-Guards. Erstellen Sie einePerson-Struktur mitname(ein Zeichen-Array von 50 Zeichen) undage(ein Integer). Definieren Sie dann eineStudent-Struktur, diePersonals ihr erstes Mitglied einbettet und eingrade-Feld (ein Integer, der ihre Punktzahl darstellt) hinzufügt. Deklarieren Sie zwei Funktionen:set_person_age, die einenStudent*und einen neuen Alterswert entgegennimmt, undprint_student, die einenStudent*entgegennimmt und alle Informationen anzeigt.student.c: Implementieren Sie beide Funktionen. Ihreset_person_age-Funktion sollte das Alter innerhalb der eingebettetenPerson-Struktur ändern – hier üben Sie die Pfeil-Punkt-Syntax (s->person.age). Ihreprint_student-Funktion sollte auf alle Felder sowohl der eingebetteten Person als auch des Studenten selbst zugreifen und diese anzeigen.main.c: Erstellen Sie eineStudent-Variable und initialisieren Sie alle ihre Felder. Verwenden Sie dannset_person_age, um das Alter der eingebetteten Person zu aktualisieren, und rufen Sieprint_studentauf, um das Ergebnis anzuzeigen.
Sie erhalten vier Eingaben: den name des Studenten (ein String), sein initial age (ein Integer), seine grade (ein Integer) und ein new age (ein Integer zur Aktualisierung über Ihre Funktion).
Erstellen Sie in Ihrer Hauptdatei den Studenten mit den Anfangswerten, rufen Sie dann set_person_age auf, um das Alter auf den neuen Wert zu ändern, und rufen Sie schließlich print_student auf, um die aktualisierten Informationen anzuzeigen.
Ihre Ausgabe sollte wie folgt aussehen:
Name: Emma
Age: 21
Grade: 85Wobei Emma der Name ist, 21 das aktualisierte Alter (nicht das ursprüngliche Alter) und 85 die Note. Der entscheidende Lerneffekt hierbei ist das Navigieren durch die eingebettete Struktur, um sowohl die Mitglieder des Elternteils zu lesen als auch zu schreiben.
Spickzettel
Um auf Member einer eingebetteten übergeordneten Struktur (Parent Struct) von einer Funktion aus zuzugreifen, verwenden Sie eine verkettete Zugriffssyntax, die davon abhängt, ob Sie mit einem Pointer oder einem Wert arbeiten.
Bei einem Pointer auf die untergeordnete Struktur (Child Struct) verwenden Sie den Pfeil-Operator, um das eingebettete Parent-Element zu erreichen, und dann die Punkt-Notation, um auf dessen Member zuzugreifen:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Pfeil, dann Punkt
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Bei einem Wert (per Kopie übergeben) verwenden Sie durchgehend die Punkt-Notation:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Punkt, dann Punkt
}Dieses Muster — child->parent.member oder child.parent.member — bietet expliziten Zugriff auf geerbte Daten im Kompositionsmodell von C.
Probier es selbst
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// Eingaben lesen
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Zeilenumbruch entfernen
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: Eine Student Variable erstellen
// TODO: Alle Felder des student initialisieren
// - name mit strcpy in den Namen der eingebetteten person kopieren
// - Das Alter der eingebetteten person auf initial_age setzen
// - Die grade des student setzen
// TODO: set_person_age aufrufen, um das Alter auf new_age zu aktualisieren
// TODO: print_student aufrufen, um das Ergebnis anzuzeigen
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-Implementierung