resueltos - Lista enlazada Implementación en C con estructura
listas simples estructura de datos (3)
Estoy usando esta estructura como una lista vinculada:
typedef struct Node{
int value;
struct node_t* next;
}node_t;
Y todo funciona bien hasta que coloque struct node_t* next
antes del campo int value
, entonces tengo muchos valores de basura trabajando con esa estructura. ¿Se trata de implementación incorrecta o alguna otra cosa en el código?
Está intentando crear un puntero a la estructura que aún debe crear. Entonces, debería haber sido,
typedef struct Node{
int value;
struct Node* next;
}node_t;
Está utilizando un tipo no existente node_t. El tipo no existe porque el tipo struct Node
ni siquiera está completo y está usando su alias. Otra cosa que typedefs
recordar al usar typedefs
con estructuras no es usar struct keyword junto con alias, por ej.
/* This is correct */
typedef struct Node
{
int x;
struct Node *next;
} node_t;
/* while these are incorrect */
/* Prefixing struct keyword to a typedef''ed type */
struct node_t *listhead;
/* The type is inclomplete and you are using an alias of the type
which doesn''t even exist */
typedef struct Node
{
int x;
node_t *next;
};
Estás llamando a tu estructura Node
y definiendo un tipo node_t
. Entonces está usando node_t
como si fuera el nombre de la estructura y no el tipo.
Prueba esto
typedef struct node {
int value;
struct node *next;
} Node;
O
typedef struct node Node;
struct node {
int value;
Node *node;
};
Si lo llamas struct Node
, entonces
struct Node {
int value;
/* The compiler doesn''t know what `struct Node'' is yet */
struct Node *next;
/* But you can always declare pointers, even of types the compiler
* doesn''t know everything about. Because the size of a pointer
* does not depend on the type of the pointee.
*/
};
En tu ejemplo, es aún peor. Usted escribe algo que es nuevo, tal como lo entiende el compilador, para usarlo NO DEBE usar struct
. La idea detrás de la typedef
de tipos es que usted DEFINIÓ un nuevo tipo, así que suponga lo siguiente
typedef struct Node node;
luego para declarar un puntero de tipo node
( nota, nuevamente el node
ES UN TIPO ),
node *anode;
pero intentaste algo como
struct node *anode;
y está mal porque no hay ningún struct node
en el código anterior, es struct Node
.
Otro error en su código es que, el tipo node_t
no existe cuando el compilador encuentra el
struct node_t *next;
que ya está mal porque si el tipo se definió antes de la estructura que es posible así
typedef struct Node node_t
aún sería incorrecto usar struct
en el tipo node_t
, porque para el compilador node_t
no es una struct
, es un tipo nuevo, que a su vez es simplemente un alias para struct Node
.
Las estructuras de desintegración de tipos en mi experiencia son más problemas que beneficios de todos modos. Y no es tan difícil escribir struct Something
lugar de simplemente Something
. También tiene el beneficio de ser más explícito, de modo que si otro programador lee tu código, inmediatamente sabrá que Something
es una struct
.
Nota : deliberadamente cambié el nombre a node
porque se considera mala práctica _t
tus propios tipos definidos con _t
. No es necesariamente algo malo, pero a lo largo de los años que he estado trabajando con esto desarrollé algunos hábitos y uno de ellos es no usar _t
como sufijo para mis propios tipos definidos. Que por cierto solo existen en mi código si mejoran mucho la legibilidad. De lo contrario, simplemente uso el nombre de la estructura con la palabra clave struct
.