Ich sehe, dass hier eine Klarstellung angebracht ist. C und C++ definieren Typen nicht unterschiedlich. C++ war ursprünglich nichts weiter als ein zusätzlicher Satz von Includes auf C.
Das Problem, das praktisch alle C/C++-Entwickler heute haben, ist, dass a) die Universitäten die Grundlagen nicht mehr lehren und b) die Leute den Unterschied zwischen einer Definition und einer Deklaration nicht verstehen.
Der einzige Grund, warum es solche Deklarationen und Definitionen gibt, ist, dass der Linker Adressoffsets für die Felder in der Struktur berechnen kann. Das ist der Grund, warum die meisten Leute mit Code durchkommen, der eigentlich falsch geschrieben ist - weil der Compiler in der Lage ist, die Adressierung zu bestimmen. Das Problem entsteht, wenn jemand versucht, etwas zu tun, das weiter fortgeschritten ist, wie eine Warteschlange oder eine verknüpfte Liste, oder eine O/S-Struktur als Huckepack zu verwenden.
Eine Deklaration beginnt mit "struct", eine Definition beginnt mit "typedef".
Darüber hinaus hat eine Struktur ein Vorwärtsdeklarationslabel und ein Definitionslabel. Die meisten Leute wissen das nicht und verwenden das Label für die Vorwärtsdeklaration als Definitionslabel.
Falsch:
struct myStruct
{
int field_1;
...
};
Sie haben lediglich die Vorwärtsdeklaration verwendet, um die Struktur zu kennzeichnen, so dass der Compiler sie kennt, aber es handelt sich nicht um einen tatsächlich definierten Typ. Der Compiler kann die Adressierung berechnen - aber das ist nicht die Art und Weise, wie sie verwendet werden sollte, aus Gründen, die ich gleich zeigen werde.
Diejenigen, die diese Form der Deklaration verwenden, müssen praktisch immer "struct" in jeden Verweis darauf schreiben, da es sich nicht um einen offiziellen neuen Typ handelt.
Stattdessen sollte jede Struktur, die nicht auf sich selbst verweist, nur auf diese Weise deklariert und definiert werden:
typedef struct
{
field_1;
...
}myStruct;
Jetzt ist es ein echter Typ, und wenn Sie ihn verwenden, können Sie ihn als "myStruct" verwenden, ohne das Wort "struct" voranstellen zu müssen.
Wenn Sie eine Zeigervariable auf diese Struktur wünschen, fügen Sie ein sekundäres Label ein:
typedef struct
{
field_1;
...
}myStruct,*myStructP;
Jetzt haben Sie eine Zeigervariable auf diese Struktur, die an die Struktur angepasst ist.
VORWÄRTSERKLÄRUNG
Jetzt kommt der Clou, wie die Vorwärtserklärung funktioniert. Wenn Sie einen Typ erstellen wollen, der auf sich selbst verweist, wie eine verknüpfte Liste oder ein Warteschlangenelement, müssen Sie eine Vorwärtsdeklaration verwenden. Der Compiler betrachtet die Struktur erst nach dem Semikolon am Ende als definiert, also wird sie einfach vor diesem Punkt deklariert.
typedef struct myStructElement
{
myStructElement* nextSE;
field_1;
...
}myStruct;
Jetzt weiß der Compiler, dass er zwar noch nicht weiß, was der ganze Typ ist, aber er kann ihn trotzdem mit der Vorwärtsreferenz referenzieren.
Bitte deklarieren und typisieren Sie Ihre Strukturen korrekt. Dafür gibt es tatsächlich einen Grund.
1 Stimmen
Ich habe gerade hier auf SO gelesen, dass die zweite Option einen Compiler-Fehler verursachen würde?! "Übergabe eines Arguments mit inkompatiblem Zeigertyp" stackoverflow.com/questions/12708897/
8 Stimmen
Eine bessere Antwort (meiner Meinung nach) finden Sie unter aquí .