selvreferer struct definisjon?

stemmer
105

Jeg har ikke vært å skrive C på veldig lenge, og så jeg er ikke sikker på hvordan jeg skal gå om du gjør disse slags rekursive ting ... Jeg ønsker hver celle til å inneholde en annen celle, men jeg får en feilmelding langs linjene av feltet 'barn' har ufullstendig type. Hva skjer?

typedef struct Cell {
  int isParent;
  Cell child;
} Cell;
Publisert på 26/02/2009 klokken 00:47
kilden bruker
På andre språk...                            


9 svar

stemmer
154

Klart en celle kan ikke inneholde annen celle som det blir en uendelig rekursjon.

Men en celle kan inneholde en peker til en annen celle.

typedef struct Cell {
  bool isParent;
  struct Cell* child;
} Cell;
Svarte 26/02/2009 kl. 00:52
kilden bruker

stemmer
21

I C, kan du ikke referere til typedef at du oppretter innenfor selve strukturen. Du må bruke strukturen navn, som i følgende testprogrammet:

#include <stdio.h>
#include <stdlib.h>

typedef struct Cell {
  int cellSeq;
  struct Cell* next; /* 'tCell *next' will not work here */
} tCell;

int main(void) {
    int i;
    tCell *curr;
    tCell *first;
    tCell *last;

    /* Construct linked list, 100 down to 80. */

    first = malloc (sizeof (tCell));
    last = first;
    first->cellSeq = 100;
    first->next = NULL;
    for (i = 0; i < 20; i++) {
        curr = malloc (sizeof (tCell));
        curr->cellSeq = last->cellSeq - 1;
        curr->next = NULL;
        last->next = curr;
        last = curr;
    }

    /* Walk the list, printing sequence numbers. */

    curr = first;
    while (curr != NULL) {
        printf ("Sequence = %d\n", curr->cellSeq);
        curr = curr->next;
    }

    return 0;
}

Selv om det er nok mye mer komplisert enn dette i standarden, kan du tenke på det som kompilatoren vet om struct Cellpå den første linjen i typedef, men ikke vite om tCellfør den siste linje :-) Det er slik jeg husker den regelen.

Svarte 26/02/2009 kl. 01:27
kilden bruker

stemmer
13

Fra teoretisk synspunkt, kan Språk bare støtte selvrefererende strukturer ikke selv inkluderende strukturer.

Svarte 29/07/2009 kl. 19:13
kilden bruker

stemmer
12

Det er liksom en vei rundt dette:

struct Cell {
  bool isParent;
  struct Cell* child;
};

struct Cell;
typedef struct Cell Cell;

Hvis du definerer det slik, det ordentlig forteller kompilatoren at struct Cell og vanlig ol'-celle er de samme. Så du kan bruke Cell akkurat som vanlig. Har fortsatt å bruke struct Cell innsiden av den første erklæringen seg selv.

Svarte 29/07/2009 kl. 19:05
kilden bruker

stemmer
7

Jeg vet dette innlegget er gammelt, men å få den effekten du er ute etter, kan du prøve følgende:

#define TAKE_ADVANTAGE

/* Forward declaration of "struct Cell" as type Cell. */
typedef struct Cell Cell;

#ifdef TAKE_ADVANTAGE
/*
   Define Cell structure taking advantage of forward declaration.
*/
struct Cell
{
   int isParent;
   Cell *child;
};

#else

/*
   Or...you could define it as other posters have mentioned without taking
   advantage of the forward declaration.
*/
struct Cell
{
   int isParent;
   struct Cell *child;
};

#endif

/*
    Some code here...
*/

/* Use the Cell type. */
Cell newCell;

I begge de to tilfellene som er nevnt i koden fragment ovenfor, må du deklarere barnet Cell struktur som en peker. Hvis du ikke gjør det, så vil du få "feltet 'barn' har ufullstendig type" feil. Årsaken er at "struct Cell" må defineres for at kompilatoren å vite hvor mye plass å fordele når den brukes.

Hvis du forsøker å bruke "struct Cell" inne i definisjonen av "struct Cell", da kompilatoren kan ennå ikke vet hvor mye plass "struct Cell" er ment å ta. Men vet kompilatoren allerede hvor mye plass en peker tar, og (med fremover erklæringen) den vet at "Cell" er en type "struct Cell" (selv om det ennå ikke vet hvor stor en "struct Cell" er ). Så kan kompilatoren definere en "Cell *" i struct som blir definert.

Svarte 24/03/2012 kl. 01:47
kilden bruker

stemmer
3

Lar gå gjennom grunnleggende definisjonen av typedef. typedef bruker å definere et alias til en eksisterende datatype, enten det er brukerdefinert eller innebygget.

typedef <data_type> <alias>;

for eksempel

typedef int scores;

scores team1 = 99;

Forvirring her er med selvrefererende struktur, på grunn av et medlem av samme datatype som ikke definerer tidligere. Så i standard måte kan du skrive koden som: -

//View 1
typedef struct{ bool isParent; struct Cell* child;} Cell;

//View 2
typedef struct{
  bool isParent;
  struct Cell* child;
} Cell;

//Other Available ways, define stucture and create typedef
struct Cell {
  bool isParent;
  struct Cell* child;
};

typedef struct Cell Cell;

Men siste alternativet øke noen ekstra linjer og ord med vanligvis vi ikke ønsker å gjøre (vi er så lat at du vet;)). Så foretrekker View 2.

Svarte 23/12/2014 kl. 10:19
kilden bruker

stemmer
2

En annen passende metode er å pre-typedef struktur med, struktur tag som:

//declare new type 'Node', as same as struct tag
typedef struct Node Node;
//struct with structure tag 'Node'
struct Node
{
int data;
//pointer to structure with custom type as same as struct tag
Node *nextNode;
};
//another pointer of custom type 'Node', same as struct tag
Node *node;
Svarte 24/05/2016 kl. 18:43
kilden bruker

stemmer
2

En struktur som inneholder en referanse til seg selv. En vanlig forekomst av dette i en struktur som beskriver en node for en koblingsliste. Hver node behov for en referanse til den neste node i kjeden.

struct node
{
       int data;
       struct node *next; // <-self reference
};
Svarte 24/10/2010 kl. 13:10
kilden bruker

stemmer
1

Alle tidligere svarene er flott, jeg tenkte bare å gi et innblikk i hvorfor en struktur ikke kan inneholde en forekomst av sin egen type (ikke en referanse).

er det svært viktig å merke seg at strukturene er 'verdi' typer dvs. de inneholder den faktiske verdien, så når du deklarerer en struktur kompilatoren har til å bestemme hvor mye minne som skal tildeles en forekomst av det, så det går gjennom alle sine medlemmer og legger opp sitt minne til å finne ut av i løpet av hele minnet av struct, men hvis kompilatoren funnet en forekomst av samme struct inne så er dette et paradoks (dvs. for å vite hvor mye minne struct en tar du må bestemme hvor mye minne struct A tar!).

Men referansetyper er forskjellige, hvis en struct 'A' inneholder en 'referanse' til en forekomst av sin egen type, selv om vi ikke vet ennå hvor mye minne som er allokert til det, vet vi hvor mye minne som er tildelt til en minne adresse (dvs. referanse).

HTH

Svarte 11/12/2016 kl. 17:28
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more