Nun, der offensichtliche Unterschied in Ihrem main
demonstriert:
struct foo a;
bar b;
baz c;
Die erste Erklärung ist ein un- typedef
ed struct
und benötigt das struct
Schlüsselwort zu verwenden. Die zweite ist eine typedef
ed anonyme struct
, und so verwenden wir den typedef
Namen. Die dritte kombiniert sowohl die erste als auch die zweite: Ihr Beispiel verwendet baz
(was kurz ist), könnte aber genauso gut struct _baz
mit demselben Effekt verwenden.
Update: larsmans' answer erwähnt einen häufigeren Fall, in dem Sie mindestens struct x { }
verwenden müssen, um eine verkettete Liste zu erstellen. Der zweite Fall wäre hier nicht möglich (es sei denn, Sie verzichten auf Vernunft und verwenden stattdessen eine void *
), weil die struct
anonym ist, und die typedef
nicht passiert, bis die struct
definiert ist, so dass Sie keine Möglichkeit haben, ein (typsicheres)) Zeiger auf den struct
Typ selbst. Die erste Version funktioniert gut für diese Verwendung, aber die dritte wird meiner Erfahrung nach bevorzugt. Gib ihm dafür ein paar Worte.
Ein feinerer Unterschied liegt in der Namespace-Platzierung. In C werden struct
Tags in einem separaten Namespace von anderen Namen platziert, aber typedef
Namen sind nicht. So ist die folgende Rechts:
struct test {
// contents
};
struct test *test() {
// contents
}
Aber die folgende ist nicht, weil es eindeutig ist, was der Name test
ist:
typedef struct {
// contents
} test;
test *test() {
// contents
}
typedef
der Name kürzer macht (immer ein Pluspunkt), aber es fügt es in denselben Namensraum ein wie Ihre Variablen und Funktionen. Normalerweise ist das kein Problem, aber es ist ein subtiler Unterschied, der über die einfache Verkürzung hinausgeht.
Dies beantwortet nicht Ihre Frage für C, aber ich glaube, sie sind alle korrekt für C++, obwohl die erste bevorzugt wird. Das mag sich auch zwischen verschiedenen Versionen von C geändert haben, aber ich werde jemand anderen damit sprechen lassen, da ich kein Experte für die Geschichte von C/C++ bin. –
C++ ist anders: Wenn Sie 'struct Foo {};' oder 'class Foo {};' dort schreiben, erhalten Sie 'Foo' kostenlos ohne' typedef'. –
Sie werden immer noch funktionieren, auch wenn sie etwas andere Dinge tun (wie den Namespace mit zusätzlichen Tags verschmutzen). –