Forward-Deklaration einer Struktur in C?

Lesezeit: 5 Minuten

Benutzeravatar von user1128265
Benutzer1128265

#include <stdio.h>

struct context;

struct funcptrs{
  void (*func0)(context *ctx);
  void (*func1)(void);
};

struct context{
    funcptrs fps;
}; 

void func1 (void) { printf( "1\n" ); }
void func0 (context *ctx) { printf( "0\n" ); }

void getContext(context *con){
    con=?; // please fill this with a dummy example so that I can get this working. Thanks.
}

int main(int argc, char *argv[]){
 funcptrs funcs = { func0, func1 };
   context *c;
   getContext(c);
   c->fps.func0(c);
   getchar();
   return 0;
}

Mir fehlt hier etwas. Bitte helfen Sie mir, dies zu beheben. Vielen Dank.

  • C lässt Sie nicht einfach sagen context *whatever;, macht es? Ich dachte, es hat dich dazu gebracht, es zu sagen struct context *whatever;

    – chao

    3. April 2012 um 18:53 Uhr


Michaels Benutzeravatar
Michael

Eine Struktur (ohne Typedef) muss (oder sollte) oft mit dem Schlüsselwort struct versehen sein, wenn sie verwendet wird.

struct A;                      // forward declaration
void function( struct A *a );  // using the 'incomplete' type only as pointer

Wenn Sie Ihre Struktur eingeben, können Sie das Schlüsselwort struct weglassen.

typedef struct A A;          // forward declaration *and* typedef
void function( A *a );

Beachten Sie, dass es zulässig ist, den Strukturnamen wiederzuverwenden

Versuchen Sie, die Vorwärtsdeklaration in Ihrem Code wie folgt zu ändern:

typedef struct context context;

Es ist möglicherweise besser lesbar, ein Suffix hinzuzufügen, um den Strukturnamen und den Typnamen anzugeben:

typedef struct context_s context_t;

  • Nett! Ich verwende die letzte Methode, die Sie erwähnt haben, mit einer leichten Variation: typedef struct context_s context; Ist schön, wenn Sie wissen, dass Sie NIE das Token “context_s” verwenden werden, sondern “context”.

    – KANJICODER

    20. Juli 2019 um 23:16 Uhr

Versuche dies

#include <stdio.h>

struct context;

struct funcptrs{
  void (*func0)(struct context *ctx);
  void (*func1)(void);
};

struct context{
    struct funcptrs fps;
}; 

void func1 (void) { printf( "1\n" ); }
void func0 (struct context *ctx) { printf( "0\n" ); }

void getContext(struct context *con){
    con->fps.func0 = func0;  
    con->fps.func1 = func1;  
}

int main(int argc, char *argv[]){
 struct context c;
   c.fps.func0 = func0;
   c.fps.func1 = func1;
   getContext(&c);
   c.fps.func0(&c);
   getchar();
   return 0;
}

  • Es wäre klarer, nur zu sagen, was im Code des OP geändert werden muss.

    – Sidcha

    25. Dezember 2019 um 6:53 Uhr

Benutzeravatar von Lewis Kelsey
Lewis Kelsey

#include <stdio.h>
struct b; // not needed because:
struct a {
    struct b * pb;  //this member definition also forward declares struct b
    int c;
};

typedef struct a a // needed for a but not struct a because:
struct b {
    struct a* pa;     //this member definition also forward declares struct a
    a * pa1;
    void * c;
};

int main() {
    printf("Hello, world!");
    return 0;
}

Grundsätzlich müssen Sie niemals forward deklarieren struct b allein, da es immer den partiellen Typ in der Zeile selbst deklariert, wenn Sie es verwenden, um eine reine Deklaration durchzuführen, also ist dies redundanter Code. Der einzige Vorteil dieser Art von Forward-Deklaration ist, dass sie mit einer Typedef verwendet werden kann. In C++ brauchen Sie die Typedef nicht, da sich struct und typedefs im selben Bezeichner-Namensraum befinden, daher also struct b wird nützlich, weil es jetzt deklariert balso werden Sie es in C++ sehen.

Der springende Punkt ist, wenn dieser Typ nicht abgeschlossen ist, bevor Sie ihn verwenden, um etwas zu deklarieren, das eigentlich eine vorläufige Definition und keine Deklaration ist (so struct e f im Datei-/Blockbereich ohne extern), das kein Zeiger ist, oder wenn Sie versuchen, den Zeiger zu dereferenzieren, wenn es sich um einen Zeiger handelt, erhalten Sie einen unvollständigen Typfehler.

Es ist also eher so, dass Sie einen unvollständigen Typ verwenden können. Vergessen Sie die Vorwärtsdeklaration, da dies keine separate Aktion ist. Es ist Teil der Linie struct g* h. Sie müssen niemals eine Forward-Deklaration verwenden, die etwas anderes tatsächlich benötigt (es sei denn, es handelt sich um eine Typedef), da sie einen Forward-Deklarationsteil in einer eigenen Zeile hat.

Die Möglichkeit, einen unvollständigen Typ zu verwenden, ermöglicht es, den Typ später zu vervollständigen, bevor er verwendet wird. Die Vorteile der Forward-Deklaration werden normalerweise so erklärt, dass der Header, der die vollständige Definition in C++ enthält, nicht eingeschlossen werden muss, wenn ein Zeiger auf den Typ verwendet wird, sondern nur class bar und dann bar *oder natürlich nur mit class bar* ohne class bar Zeile, wenn dieses bestimmte Mitglied nie verwendet wird.

Sie können auch keinen Typ mit unvollständiger Größe als Strukturmitglied verwenden (wenn die Größe bis zu einem solchen Code unbekannt ist), selbst wenn die Struktur niemals zum Deklarieren / Definieren einer Variablen verwendet wird. Ich denke, das liegt daran, dass die Struktur ein Typ ist und wenn Sie die vollständige Definition eines Typs angeben, was Sie nur tun können einmal, muss es eine vollständige Größe haben, nicht unvollständig (mit einem Mitglied unbekannter Größe), damit der Typ unbrauchbar wäre. Diese Struktur, die die unvollständige Struktur enthält, wird niemals referenziert, während Sie kann Verweisen Sie auf einen unvollständigen Typ mit unvollständiger Größe im Gegensatz zu einem vollständigen Typ mit unvollständiger Größe (solange Sie nichts damit definieren), und Sie können einen Zeiger mit referenzieren, aber nicht respektieren (eine Adresse kann darin gespeichert werden). unvollständiger Typ, weil er die vollständige Größe hat. Sie können auf den Speicher verweisen, solange sein unvollständiger Typ keine unvollständige Größe zur Folge hat. extern struct i j im Datei- / Blockbereich ist zulässig, da es niemals benötigt wird, es sei denn j im Code referenziert wird, bis zu welchem ​​Zeitpunkt der Typ vollständig sein muss.

1409630cookie-checkForward-Deklaration einer Struktur in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy