Ich habe C nicht sehr lange geschrieben und bin mir daher nicht sicher, wie ich diese Art von rekursiven Dingen ausführen soll ... Ich möchte, dass jede Zelle eine andere Zelle enthält, aber ich erhalte einen Fehler entlang der Zeilen von "Feld 'Kind' hat unvollständigen Typ". Was geht?
typedef struct Cell {
int isParent;
Cell child;
} Cell;
Antworten:
Es ist klar, dass eine Zelle keine andere Zelle enthalten kann, da dies zu einer nie endenden Rekursion wird.
Eine Zelle kann jedoch einen Zeiger auf eine andere Zelle enthalten.
quelle
Cell
ist noch nicht im Geltungsbereich.Cell*
zucell->child
.struct
s in C im Grunde nur alle ihre Werte nebeneinander speichern, ist es unmöglich, eine Struktur tatsächlich in sich selbst zu speichern (da diese Struktur eine andere enthalten müsste usw., was zu einer Speicherstruktur von unendlicher Größe führt). .struct Cell
finden Sie in dieser Antwort .In C können Sie nicht auf das Typedef verweisen, das Sie mit der Struktur selbst erstellen. Sie müssen den Strukturnamen wie im folgenden Testprogramm verwenden:
Obwohl es im Standard wahrscheinlich viel komplizierter ist als dies, können Sie sich vorstellen, dass der Compiler
struct Cell
in der ersten Zeile der,typedef
abertCell
erst in der letzten Zeile davon weiß :-) So erinnere ich mich an diese Regel.quelle
Aus theoretischer Sicht können Sprachen nur selbstreferenzielle Strukturen unterstützen, keine selbstinklusiven Strukturen.
quelle
Es gibt eine Art Weg, dies zu umgehen:
Wenn Sie es so deklarieren, teilt es dem Compiler ordnungsgemäß mit, dass struct Cell und plain-ol'-cell identisch sind. Sie können Cell also wie gewohnt verwenden. Die Strukturzelle muss jedoch immer noch in der ursprünglichen Deklaration selbst verwendet werden.
quelle
struct Cell;
wieder geschriebenstruct Cell
.struct Cell;
redundant wird. Wenn Sie jedoch aus irgendeinem Grund die letzten beiden Zeilen in eine Header-Datei einfügen, die Sie einschließen, bevor Sie dieCell
Struktur mit den ersten vier Zeilen definieren, ist das Extrastruct Cell;
erforderlich.typedef struct Cell Cell;
und es wirdCell
ein Alias für erstelltstruct Cell
. Es spielt keine Rolle, ob der Compiler zuvor gesehenstruct Cell { .... }
hat.Ich weiß, dass dieser Beitrag alt ist. Um jedoch den gewünschten Effekt zu erzielen, sollten Sie Folgendes versuchen:
In jedem der beiden im obigen Codefragment genannten Fälle MÜSSEN Sie Ihre untergeordnete Zellstruktur als Zeiger deklarieren. Wenn Sie dies nicht tun, wird der Fehler "Feld 'Kind' hat unvollständigen Typ" angezeigt. Der Grund dafür ist, dass "struct Cell" definiert werden muss, damit der Compiler weiß, wie viel Speicherplatz bei seiner Verwendung zugewiesen werden muss.
Wenn Sie versuchen, "struct Cell" in der Definition von "struct Cell" zu verwenden, kann der Compiler noch nicht wissen, wie viel Speicherplatz "struct Cell" einnehmen soll. Der Compiler weiß jedoch bereits, wie viel Speicherplatz ein Zeiger benötigt, und (mit der Vorwärtsdeklaration) weiß er, dass "Zelle" eine Art "Strukturzelle" ist (obwohl er noch nicht weiß, wie groß eine "Strukturzelle" ist ). Der Compiler kann also eine "Zelle *" innerhalb der Struktur definieren, die definiert wird.
quelle
Lassen Sie uns die grundlegende Definition von typedef durchgehen. typedef wird verwendet, um einen Alias für einen vorhandenen Datentyp zu definieren, der entweder benutzerdefiniert oder integriert ist.
beispielsweise
Verwechslung besteht hier mit der selbstreferenziellen Struktur aufgrund eines Mitglieds desselben Datentyps, der zuvor nicht definiert wurde. Standardmäßig können Sie Ihren Code also wie folgt schreiben: -
Aber letzte Option erhöht einige zusätzliche Zeilen und Wörter mit normalerweise wollen wir nicht (wir sind so faul, wie Sie wissen;)). Also lieber View 2.
quelle
typedef
Syntax ist falsch (zB berücksichtigentypedef int (*foo)(void);
). Ihre Beispiele für Ansicht 1 und Ansicht 2 funktionieren nicht: Sie bildenstruct Cell
einen unvollständigen Typ, sodass Sie sie nichtchild
in Ihrem Code verwenden können.Eine andere bequeme Methode besteht darin, die Struktur mit dem Struktur-Tag wie folgt vorab zu definieren:
quelle
Eine Struktur, die einen Verweis auf sich selbst enthält. Dies tritt häufig in einer Struktur auf, die einen Knoten für eine Verknüpfungsliste beschreibt. Jeder Knoten benötigt einen Verweis auf den nächsten Knoten in der Kette.
quelle
Alle vorherigen Antworten sind großartig. Ich wollte nur einen Einblick geben, warum eine Struktur keine Instanz ihres eigenen Typs enthalten kann (keine Referenz).
Es ist sehr wichtig zu beachten, dass Strukturen 'Wert'-Typen sind, dh sie enthalten den tatsächlichen Wert. Wenn Sie also eine Struktur deklarieren, muss der Compiler entscheiden, wie viel Speicher einer Instanz davon zugewiesen werden soll, damit er alle seine Mitglieder durchläuft und hinzufügt Erhöhen Sie den Speicher, um den Gesamtspeicher der Struktur zu ermitteln. Wenn der Compiler jedoch eine Instanz derselben Struktur im Inneren gefunden hat, ist dies ein Paradoxon (dh um zu wissen, wie viel Speicher Struktur A benötigt, müssen Sie entscheiden, wie viel Speicher erforderlich ist Struktur A dauert!).
Referenztypen sind jedoch unterschiedlich, wenn eine Struktur 'A' eine 'Referenz' auf eine Instanz ihres eigenen Typs enthält, obwohl wir noch nicht wissen, wie viel Speicher ihr zugewiesen ist, wissen wir, wie viel Speicher einem Speicher zugewiesen ist Adresse (dh die Referenz).
HTH
quelle