Ich habe C noch nicht lange geschrieben und bin mir daher nicht sicher, wie ich diese Art von rekursiven Dingen anstellen 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 ist los?
typedef struct Cell {
int isParent;
Cell child;
} Cell;
PS Eigentlich gibt es “struct Cell” zu “Cell” (das ist ein gängiges Muster)
– David Z
26. Februar 2009 um 1:10 Uhr
er verwendet wahrscheinlich einen C++-Compiler. er sollte auch _Bool verwenden, wenn es wirklich C ist.
– Nabi
26. Februar 2009 um 1:52 Uhr
Er sollte int verwenden, wenn es wirklich C ist 🙂
– paxdiablo
26. Februar 2009 um 2:04 Uhr
Wieso den? C99 hat bool – Sie müssen nur einfügen
– Jonathan Leffler
26. Februar 2009 um 4:21 Uhr
mögliches Duplikat von C: Zeiger auf Struct in der Struct-Definition
– Jonathan Leffler
24. Mai 2014 um 6:51 Uhr
Andreas Grant
Eindeutig A Cell kann kein anderes enthalten Cell da es zu einer nie endenden Rekursion wird.
Jedoch ein Cell KANN einen Zeiger auf einen anderen enthalten Cell.
@cs01 Nein, Cell ist noch nicht im Geltungsbereich.
– fredoverflow
30. Dezember 2015 um 13:28 Uhr
Es möchten Sinn ergeben. Python erlaubt es und erlaubt sogar die Serialisierung eines solchen Objekts. Warum nicht C++?
– noɥʇʎʀʎzɐɹƆ
6. Juni 2016 um 1:06 Uhr
Ich erhalte Warnungen, wenn ich versuche, etwas zuzuweisen Cell* zu cell->child.
– Tomáš Zato
26. November 2016 um 23:02 Uhr
@noɥʇʎʀʎzɐɹƆ Weil Python Zeiger abstrahiert, damit Sie sie nicht bemerken. Seit structs in C im Grunde nur alle ihre Werte nebeneinander speichern, wäre es unmöglich, eine Struktur tatsächlich in sich selbst zu speichern (da diese Struktur eine andere enthalten müsste und so weiter, was zu einer Speicherstruktur unendlicher Größe führen würde).
– jazzpi
3. Februar 2017 um 15:31 Uhr
Zur Erläuterung der Verwendung von struct Cellsiehe diese Antwort.
– wizzwizz4
27. Mai 2017 um 13:53 Uhr
paxdiablo
In C können Sie nicht auf die Typedef verweisen, die Sie innerhalb der Struktur selbst erstellen. Sie müssen den Strukturnamen wie im folgenden Testprogramm verwenden:
#include <stdio.h>
#include <stdlib.h>
typedef struct Cell {
int cellSeq;
struct Cell* next; /* 'tCell *next' will not work here */
} tCell;
int main(void) {
int i;
tCell *curr;
tCell *first;
tCell *last;
/* Construct linked list, 100 down to 80. */
first = malloc (sizeof (tCell));
last = first;
first->cellSeq = 100;
first->next = NULL;
for (i = 0; i < 20; i++) {
curr = malloc (sizeof (tCell));
curr->cellSeq = last->cellSeq - 1;
curr->next = NULL;
last->next = curr;
last = curr;
}
/* Walk the list, printing sequence numbers. */
curr = first;
while (curr != NULL) {
printf ("Sequence = %d\n", curr->cellSeq);
curr = curr->next;
}
return 0;
}
Obwohl es im Standard wahrscheinlich viel komplizierter ist, können Sie sich vorstellen, dass der Compiler davon weiß struct Cell in der ersten Zeile der typedef aber nichts davon wissen tCell bis zur letzten Zeile 🙂 So habe ich diese Regel in Erinnerung.
Was ist mit C ++? Können Sie bitte die Antworten zu C ++ verlinken?
– Rimalroshan
10. Mai 2018 um 13:09 Uhr
@rimiro, die Frage war eine C-Frage. Wenn Sie die Antwort für eine C++-Variante wollen, sollten Sie das tun Fragen es als Frage.
– paxdiablo
10. Mai 2018 um 13:12 Uhr
Aus theoretischer Sicht können Sprachen nur selbstreferenzielle Strukturen unterstützen, keine selbsteinschließenden Strukturen.
Wie groß wäre aus praktischer Sicht eine solche Instanz von ‘struct Cell’ tatsächlich?
– Marsh Ray
29. Juli 2009 um 19:23 Uhr
Auf den meisten Maschinen vier Bytes größer als er selbst.
Wenn Sie es so deklarieren, teilt es dem Compiler richtig mit, dass struct Cell und plain-ol’-cell identisch sind. Sie können Cell also ganz normal verwenden. Trotzdem muss struct Cell innerhalb der anfänglichen Deklaration selbst verwendet werden.
Shawn
Ich weiß, dass dieser Beitrag alt ist, aber um den gewünschten Effekt zu erzielen, sollten Sie Folgendes versuchen:
#define TAKE_ADVANTAGE
/* Forward declaration of "struct Cell" as type Cell. */
typedef struct Cell Cell;
#ifdef TAKE_ADVANTAGE
/*
Define Cell structure taking advantage of forward declaration.
*/
struct Cell
{
int isParent;
Cell *child;
};
#else
/*
Or...you could define it as other posters have mentioned without taking
advantage of the forward declaration.
*/
struct Cell
{
int isParent;
struct Cell *child;
};
#endif
/*
Some code here...
*/
/* Use the Cell type. */
Cell newCell;
In beiden Fällen, die im obigen Codefragment erwähnt werden, MÜSSEN Sie Ihre untergeordnete Zellstruktur als Zeiger deklarieren. Wenn Sie dies nicht tun, erhalten Sie den Fehler “Feld ‘Kind’ hat unvollständigen Typ”. Der Grund dafür ist, dass “struct Cell” definiert werden muss, damit der Compiler weiß, wie viel Speicherplatz er zuordnen muss, wenn er verwendet wird.
Wenn Sie versuchen, “struct Cell” innerhalb der Definition von “struct Cell” zu verwenden, kann der Compiler noch nicht wissen, wie viel Platz “struct Cell” einnehmen soll. Der Compiler weiß jedoch bereits, wie viel Platz ein Zeiger benötigt, und er weiß (mit der Vorwärtsdeklaration), dass “Cell” eine Art “struct Cell” ist (obwohl er noch nicht weiß, wie groß eine “struct Cell” ist ). Der Compiler kann also eine “Zelle *” innerhalb der zu definierenden Struktur definieren.
Neuron
Eine weitere praktische Methode ist die Vorabtypisierung der Struktur mit dem Struktur-Tag als:
//declare new type 'Node', as same as struct tag
typedef struct Node Node;
//struct with structure tag 'Node'
struct Node
{
int data;
//pointer to structure with custom type as same as struct tag
Node *nextNode;
};
//another pointer of custom type 'Node', same as struct tag
Node *node;
vineetv2821993
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.
typedef <data_type> <alias>;
zum Beispiel
typedef int scores;
scores team1 = 99;
Die Verwirrung liegt hier bei der selbstreferenziellen Struktur aufgrund eines Mitglieds desselben Datentyps, das nicht früher definiert wurde. So können Sie Ihren Code standardmäßig wie folgt schreiben: –
Aber die letzte Option erhöht einige zusätzliche Zeilen und Wörter, die wir normalerweise nicht tun möchten (wir sind so faul, weißt du 😉 ). Also lieber Ansicht 2.
Ihre Erklärung der typedef Syntax ist falsch (betrachten Sie z typedef int (*foo)(void);). Ihre Beispiele für Ansicht 1 und Ansicht 2 funktionieren nicht: Sie machen struct Cell ein unvollständiger Typ, sodass Sie ihn nicht verwenden können child in deinem Code.
PS Eigentlich gibt es “struct Cell” zu “Cell” (das ist ein gängiges Muster)
– David Z
26. Februar 2009 um 1:10 Uhr
er verwendet wahrscheinlich einen C++-Compiler. er sollte auch _Bool verwenden, wenn es wirklich C ist.
– Nabi
26. Februar 2009 um 1:52 Uhr
Er sollte int verwenden, wenn es wirklich C ist 🙂
– paxdiablo
26. Februar 2009 um 2:04 Uhr
Wieso den? C99 hat bool – Sie müssen nur einfügen
– Jonathan Leffler
26. Februar 2009 um 4:21 Uhr
mögliches Duplikat von C: Zeiger auf Struct in der Struct-Definition
– Jonathan Leffler
24. Mai 2014 um 6:51 Uhr