Wenn diese Struktur von einer anderen Datei func.c verwendet werden soll, wie geht das?
Wenn ein Typ in einer Datei verwendet wird (dh eine func.c-Datei), muss er sichtbar sein. Der schlechteste Weg, dies zu tun, ist das Kopieren und Einfügen in jede benötigte Quelldatei.
Der richtige Weg ist, es in eine Header-Datei einzufügen und diese Header-Datei bei Bedarf einzuschließen.
Sollen wir eine neue Header-Datei öffnen und die Struktur dort deklarieren und diesen Header in die func.c aufnehmen?
Dies ist die Lösung, die mir besser gefällt, weil sie den Code sehr modular macht. Ich würde Ihre Struktur wie folgt codieren:
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
Ich würde Funktionen, die diese Struktur verwenden, in denselben Header einfügen (die Funktion, die "semantisch" Teil ihrer "Schnittstelle" ist).
Und normalerweise könnte ich die Datei nach dem Strukturnamen benennen und diesen Namen erneut verwenden, um die definierten Header-Guards auszuwählen.
Wenn Sie eine Funktion mit einem Zeiger auf die Struktur deklarieren müssen, benötigen Sie nicht die vollständige Strukturdefinition. Eine einfache Vorwärtserklärung wie:
struct a ;
Wird ausreichen, und es verringert die Kopplung.
oder können wir die Gesamtstruktur in der Header-Datei definieren und diese sowohl in source.c als auch in func.c aufnehmen?
Dies ist ein anderer Weg, der etwas einfacher, aber weniger modular ist: Einige Codes, für deren Funktion nur Ihre Struktur erforderlich ist, müssen noch alle Typen enthalten.
In C ++ könnte dies zu interessanten Komplikationen führen, aber dies ist nicht zum Thema (kein C ++ - Tag), daher werde ich nicht näher darauf eingehen.
dann, wie diese Struktur in beiden Dateien als extern deklariert wird. ?
Ich verstehe den Punkt vielleicht nicht, aber Greg Hewgill hat eine sehr gute Antwort in seinem Beitrag. Wie deklariere ich eine Struktur in einem Header, die von mehreren Dateien in c verwendet werden soll? .
sollen wir es dann wie tippen?
- Wenn Sie C ++ verwenden, tun Sie dies nicht.
- Wenn Sie C verwenden, sollten Sie.
Der Grund dafür ist, dass die Verwaltung von C-Strukturen schmerzhaft sein kann: Sie müssen das Schlüsselwort struct überall dort deklarieren, wo es verwendet wird:
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
Mit einem typedef können Sie es ohne das Schlüsselwort struct schreiben.
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
Es ist wichtig, dass Sie immer noch einen Namen für die Struktur behalten. Schreiben:
typedef struct
{
/* etc. */
} MyStruct ;
erstellt nur eine anonyme Struktur mit einem typisierten Namen, und Sie können sie nicht weiter deklarieren. Halten Sie sich also an das folgende Format:
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
Auf diese Weise können Sie MyStruct überall dort verwenden, wo Sie das Hinzufügen des Schlüsselworts struct vermeiden möchten, und MyStructTag weiterhin verwenden, wenn ein typedef nicht funktioniert (dh eine Vorwärtsdeklaration).
Bearbeiten:
Die falsche Annahme bezüglich der C99-Strukturdeklaration wurde korrigiert, wie Jonathan Leffler zu Recht bemerkte .
Bearbeiten 2018-06-01:
Craig Barnes erinnert uns in seinem Kommentar daran, dass Sie aus Gründen der Klarheit keine separaten Namen für den Strukturnamen "tag" und den Namen "typedef" verwenden müssen, wie ich es oben getan habe.
In der Tat könnte der obige Code gut geschrieben werden als:
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC, genau das macht C ++ mit seiner einfacheren Strukturdeklaration hinter den Kulissen, um die Kompatibilität mit C zu gewährleisten:
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
Zurück zu C habe ich beide Verwendungen gesehen (separate Namen und gleiche Namen), und keine hat mir bekannte Nachteile. Die Verwendung desselben Namens vereinfacht das Lesen, wenn Sie keine separaten C-Namespaces für Strukturen und andere Symbole verwenden .
struct b
, aber danna
deklariert Ihre Struktur einen Typ, der nicht verwendet wird (Sie sollten wahrscheinlich einen Mitgliedsnamen definieren, möglicherweisek
nach der inneren engen Klammer und vor dem Semikolon.