2016-04-27 17 views
0

Ich bin etwas neu zu C, ich lerne es bei uni, und ich denke, ich könnte etwas über Typedefs missverstehen. Hier ist mein Code:Die Adresse der Struktur kann nicht einer Variablen zugewiesen werden, deren Typ ein typedef Zeiger auf diese Struktur ist

struct stackNode 
{ 
    char data; 
    struct stackNode *nextPtr; 
}; 
typedef struct stackNode StackNode; 
typedef struct StackNode *StackNodePtr; 

int main() 
{ 
    StackNode stack; 
    StackNodePtr stackPtr = &stack; 
} 

Das gibt mir diese Warnung:

warning: initialization from incompatible pointer type [enabled by default] 
    StackNodePtr stackPtr = &stack; 
          ^

Allerdings, wenn ich diese Zeile mit diesem ersetzen:

StackNode *stackPtr = &stack; 

Es funktioniert gut.

Leider sehe ich hier nicht den wirklichen Unterschied. Ist nicht typedef struct StackNode *StackNodePtr; nur eine Art "Wrapper-Typ" für einen Zeiger auf die Stack-Struktur? Ich habe ein gutes Gespür für Zeiger und Strukturen, aber ich weiß nicht, was hier vor sich geht. Ich bin mir sicher, ich vermisse nur etwas Kleines.

Übrigens kompiliere ich im c89-Modus mit gcc.

+1

Beginnen Sie mit dem Entfernen der 'typedef'-Zeiger. Sie sind nur schädlich, indem sie Ihren Code verschleiern, die Semantik verbergen und schließlich zu Verwirrung führen - QED. – Olaf

+0

Und 'typedef's sind eigentlich Aliase. C wird nicht mit dem Namen, sondern mit dem kompatiblen/"echten" Typ eingegeben. – Olaf

+0

'typedef struct StackNode' Tippfehler als' typedef struct stackNode' (S und s) – BLUEPIXY

Antwort

3

Problem ist diese Art Definition:

typedef struct StackNode *StackNodePtr; 

Es gibt keine struct StackNode. Nur struct stackNode und StackNode existieren. Sie müssen also einen davon im typedef verwenden.

Aber bessere Lösung ist überhaupt nicht zu Zeiger hinter typedef zu verstecken:

  1. Es den Zeiger deutlicher sichtbar macht.
  2. Es funktioniert besser mit Typqualifikatoren wie const und volatile. Wenn Sie StackNodePtr definieren, müssen Sie möglicherweise auch ConstStackNodePtr, VolatileStackNodePtr und ConstVolatileStackNodePtr definieren.

So loszuwerden StackNodePtr und einfach die Methode verwenden Sie bereits versucht:

StackNode *stackPtr = &stack; // stackPtr is clearly a pointer 
+0

* Bessere Lösung ist, Zeiger hinter Typdef überhaupt nicht zu verstecken * Außer Sie sind Microsoft. Dann kannst du das nolens volens machen. Sorry, konnte nicht widerstehen :) :) –

+0

Der Grund, warum ich typedefs benutze, ist, weil ich eine Aufgabe mache und wir diese typedefs bekommen, die wir verwenden müssen. Dies ist wahrscheinlich, um sicherzustellen, dass wir verstehen, wie man sie verwendet, anstatt uns gute Praxis zu zeigen. Danke, dass du das herausgibst, aber ich werde sicher sein, dass du die versteckten Zeiger reduzierst, da ich sehen kann, wie schädlich es wäre. Wie auch immer Ihre Lösung funktioniert hat, in der Tat, wenn ich zurückschaue, sehe ich jetzt, dass die Zeiger-Typdefinition, die sie uns gegeben haben, nicht das Schlüsselwort struct hatte, und aus irgendeinem Grund habe ich es trotzdem geschrieben. Vielen Dank! – puggsoy

0

"stackNode" ist

typedef struct StackNode *StackNodePtr; 

(Kapital "S") in

falsch geschrieben.