Menu
Coddy logo textTech

Die First-Member-Regel

Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 29 von 61.

Wenn du eine Struktur als erstes Mitglied einer anderen Struktur einbettest, geschieht etwas Leistungsstarkes: Die Speicheradresse der äußeren Struktur ist identisch mit der Speicheradresse ihres ersten Mitglieds. Dies wird vom C-Standard garantiert.

Betrachte unser vorheriges Beispiel:

typedef struct {
    int id;
} Parent;

typedef struct {
    Parent parent;  // Erstes Mitglied
    int grade;
} Child;

Wenn du eine Child-Variable erstellst, befindet sich das Parent-Member ganz am Anfang des Speichers von Child. Das bedeutet, dass ein Zeiger auf Child auf genau dieselbe Adresse zeigt wie ein Zeiger auf sein Parent-Member.

Child c;
Child* child_ptr = &c;
Parent* parent_ptr = (Parent*)child_ptr;  // Sicherer Cast!

Beide Zeiger enthalten dieselbe Adresse. Dadurch kannst du einen Child* an jede Funktion übergeben, die einen Parent* erwartet:

void print_id(Parent* p) {
    printf("ID: %d\n", p->id);
}

// In main:
Child c;
c.parent.id = 42;
print_id((Parent*)&c);  // Funktioniert perfekt

Diese Technik bildet die Grundlage der Vererbung in C. Eine für den Basistyp geschriebene Funktion kann mit jedem abgeleiteten Typ arbeiten, solange die Basis zuerst eingebettet ist. Die Typumwandlung ist sicher, weil die Speicherlayouts perfekt übereinstimmen.

challenge icon

Aufgabe

Einfach

Erkunden wir die Regel des ersten Mitglieds, indem wir eine einfache Tierhierarchie erstellen. Du erstellst ein Animal-Struct als Basistyp und ein abgeleitetes Dog-Struct und demonstrierst anschließend, wie ein Zeiger auf Dog sicher in einen Zeiger auf Animal umgewandelt werden kann.

Die zentrale Erkenntnis, die du anwenden wirst: Wenn Animal das erste Mitglied von Dog ist, teilen sich beide Structs dieselbe Startspeicheradresse. Das bedeutet, dass du einen Dog* an jede Funktion übergeben kannst, die einen Animal* erwartet, indem du den Zeiger umwandelst.

Du wirst deinen Code auf drei Dateien verteilen:

  • animal.h: Definiere beide Structs mit Include-Schutz. Dein Animal-Struct sollte ein einziges Feld haben: legs (eine Ganzzahl, die die Anzahl der Beine angibt). Dein Dog-Struct sollte Animal als sein erstes Mitglied einbetten und ein name-Feld hinzufügen (ein Zeichenarray mit 50 Zeichen). Deklariere außerdem eine Funktion print_animal, die einen Animal*-Parameter übernimmt.
  • animal.c: Implementiere die Funktion print_animal. Diese Funktion arbeitet mit dem Basistyp. Sie kennt nur Animal und gibt aus, wie viele Beine das Tier hat.
  • main.c: Erstelle eine Dog-Variable und belege ihre Felder (sowohl die Beine des eingebetteten Tiers als auch den Namen des Hundes). Demonstriere anschließend die Regel des ersten Mitglieds, indem du deinen Dog* in einen Animal* umwandelst und ihn an print_animal übergibst. Gib außerdem den Namen des Hundes separat aus, um das vollständige Bild zu zeigen.

Du erhältst zwei Eingaben: den Namen des Hundes (eine Zeichenkette) und die Anzahl der Beine (eine Ganzzahl).

Deine Ausgabe sollte so aussehen:

Dog: Buddy
Legs: 4

Dabei ist Buddy der Name des Hundes und 4 die Anzahl der Beine. Gib zuerst den Namen des Hundes aus main.c aus und rufe dann print_animal mit dem umgewandelten Zeiger auf, um die Anzahl der Beine anzuzeigen.

Dies zeigt, wie eine für den Basistyp (Animal) geschriebene Funktion durch Zeigerumwandlung nahtlos mit einem abgeleiteten Typ (Dog) arbeiten kann: die Grundlage der Vererbung in C.

Probier es selbst

#include <stdio.h>
#include <string.h>
#include "animal.h"

int main() {
    // Eingabe lesen
    char name[50];
    int legs;
    scanf("%s", name);
    scanf("%d", &legs);
    
    // TODO: Erstelle eine Dog-Variable
    
    // TODO: Setze den Namen des Hundes mit strcpy
    
    // TODO: Setze die Anzahl der Beine (Zugriff über das eingebettete Animal)
    
    // TODO: Gib den Namen des Hundes im Format aus: "Dog: <name>"
    
    // TODO: Cast Dog* zu Animal* und rufe print_animal auf
    // Dies demonstriert die First-Member-Regel!
    
    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 Objektorientierte Programmierung

Übe selbstständig: Online-C-Compiler