Estructura dentro de estructura

3 minutos de lectura

avatar de usuario de sok
sok

Debo crear una Persona y cada Persona debe tener una Nevera. ¿Es esta la mejor manera de hacerlo? Si es así, ¿qué estoy haciendo mal? Gracias por adelantado.

typedef struct {
 int age;
 struct FRIDGE fridge;
} PERSON;

typedef struct {
 int number;
} FRIDGE;

FRIDGE fr;
fr.number=1;

PERSON me;
me.name=1;
me.fridge = fr;

Esto me da el siguiente error:

error: el campo ‘refrigerador’ tiene un tipo incompleto

  • Está utilizando una estructura anónima, por lo que no debe utilizar la struct palabra clave pero usa la typedef‘ed nombre. Cambio struct FRIDGE fridge a FRIDGE fridge

    – manav mn

    26 de diciembre de 2012 a las 13:26


  • @Manav: editar el código en la pregunta es la forma incorrecta de responderla. Edite el código de la pregunta solo para corregir el formato miserable, como una sangría incorrecta.

    – Ben Voigt

    26 de diciembre de 2012 a las 13:32

  • @BenVoigt: ¡+1 punto anotado!

    – manav mn

    26 de diciembre de 2012 a las 13:34

avatar de usuario de che
Che

struct FRIDGE es algo diferente a FRIDGE.

Necesitas usar el tipo FRIDGE en tu otra estructura.

typedef struct {
 int age;
 FRIDGE fridge;
} PERSON;

o define tu nevera como struct FRIDGE

struct FRIDGE {
 int number;
};

Además, es posible que deba definir la estructura antes de usarla (por ejemplo, encima de la persona).

avatar de usuario de manav mn
manav mn

Tienes que usar miembros de FRIDGE, después de eliminar todas las advertencias y errores. Declarar FRIDGE antes de PERSON

me.fridge.number = 1

EDITADO: Encontré el error. Está utilizando una estructura anónima, por lo que no debe utilizar la struct palabra clave pero usa la typedefnombre de ed.

Cambio struct FRIDGE fridge
a FRIDGE fridge

  • Ese no es el problema, el dialecto moderno de C admite la asignación directa de estructuras. Vea el mensaje de error.

    – Che

    26 de diciembre de 2012 a las 12:36

  • Si envía una declaración de FRIDGE, el error se ha ido. Es siempre aconsejable para asignar valores a los miembros de la estructura y no a toda la estructura a menos que haga algo como memset. Esto evita errores en el futuro cuando se agreguen más miembros de estructura a su declaración.

    – manav mn

    26 de diciembre de 2012 a las 12:39

  • Bueno, eso es lo que está haciendo el código original. Tú tienes fr inicializado usando el miembro, y luego solo está colocando la estructura en la otra estructura. No habrá ningún error si agrega más miembros. (Además, a veces quiero que mi código falle cuando se amplían las estructuras subyacentes. Puede ser un recordatorio útil para agregar la inicialización faltante).

    – Che

    26 de diciembre de 2012 a las 12:47

  • … sin mencionar que su segunda línea asigna una estructura de refrigerador a int.

    – Che

    26 de diciembre de 2012 a las 12:49

  • @che: cuando declaras struct A { struct B xyz;}; la línea anterior debe ser struct B; o una definición completa de struct B de lo contrario, ¿cómo calcularía el compilador el tamaño de struct B y sepa cuánta memoria asignar para su último struct A??

    – manav mn

    26 de diciembre de 2012 a las 12:53

El uso de typedefs con sus estructuras lo llevará a este tipo de enredos. La palabra clave struct delante de un identificador de etiqueta struct es cómo se supone que se deben usar las estructuras, esto también es más explícito y más fácil de leer.

Hay una entrada de blog larga y buena con todos los detalles aquí.
https://www.microforum.cc/blogs/entry/21-how-to-struct-lessons-on-structures-in-c/

Pero, en resumen, lo que realmente quieres hacer es omitir los typedef como este

struct FRIDGE;  // This is a forward declaration, now an incomplete type

struct PERSON{
 int age;
 struct FRIDGE fridge;
};

struct FRIDGE{
 int number;
};

struct FRIDGE fr;
fr.number=1;

struct PERSON me;
me.name=1;
me.fridge = fr;

Linus Torvalds también habló sobre esto una vez, con un razonamiento muy sólido de por qué usar typedefs en todas sus estructuras es confuso y malo.

https://yarchive.net/comp/linux/typedefs.html

Haga la declaración directa de struct FRIDGE;

O,

dar la definición de FRIDGE antes de usarlo en struct PERSON

¿Ha sido útil esta solución?