Si tengo un archivo source.c con una estructura:
struct a {
int i;
struct b {
int j;
}
};
¿Cómo se puede utilizar esta estructura en otro archivo (es decir func.c
)?
¿Debo crear un nuevo archivo de encabezado, declarar la estructura allí e incluir ese encabezado func.c
?
¿O debería definir toda la estructura en un archivo de encabezado e incluir eso en ambos source.c
y func.c
? ¿Cómo se puede declarar la estructura extern
en ambos archivos?
¿Debería typedef
hacerlo? ¿Si es así, cómo?
struct b
, pero luego su estructuraa
declara un tipo que no se utiliza (probablemente debería definir un nombre de miembro, tal vezk
, después de la llave de cierre interior y antes del punto y coma.Respuestas:
si esta estructura va a ser utilizada por algún otro archivo func.c, ¿cómo hacerlo?
Cuando se utiliza un tipo en un archivo (es decir, archivo func.c), debe ser visible. La peor forma de hacerlo es copiarlo y pegarlo en cada archivo fuente que lo necesite.
La forma correcta es ponerlo en un archivo de encabezado e incluir este archivo de encabezado cuando sea necesario.
¿Abriremos un nuevo archivo de encabezado y declararemos la estructura allí e incluiremos ese encabezado en la función c?
Esta es la solución que más me gusta, porque hace que el código sea altamente modular. Codificaría tu estructura como:
Pondría funciones que usan esta estructura en el mismo encabezado (la función que es "semánticamente" parte de su "interfaz").
Y, por lo general, podría nombrar el archivo después del nombre de la estructura y usar ese nombre nuevamente para elegir la definición de guardias de encabezado.
Si necesita declarar una función usando un puntero a la estructura, no necesitará la definición completa de la estructura. Una simple declaración hacia adelante como:
Será suficiente, y disminuye el acoplamiento.
¿O podemos definir la estructura total en el archivo de encabezado e incluirla tanto en source.cy en func.c?
Esta es otra forma, algo más fácil, pero menos modular: algún código que necesite solo su estructura para funcionar, aún tendría que incluir todos los tipos.
En C ++, esto podría conducir a una complicación interesante, pero esto está fuera de tema (sin etiqueta C ++), así que no daré más detalles.
luego, cómo declarar esa estructura como externa en ambos archivos. ?
Tal vez no entiendo el punto, pero Greg Hewgill tiene una muy buena respuesta en su publicación ¿Cómo declarar una estructura en un encabezado que va a ser utilizado por múltiples archivos en c? .
¿Lo escribiremos entonces cómo?
La razón es que la administración de estructuras en C puede ser un problema: debe declarar la palabra clave struct en todos los lugares donde se usa:
Mientras que un typedef le permitirá escribirlo sin la palabra clave struct.
Es importante que aún conserve un nombre para la estructura. Escritura:
simplemente creará una estructura anónima con un nombre typedef-ed, y no podrá declararlo hacia adelante. Así que mantén el siguiente formato:
Por lo tanto, podrá usar MyStruct donde quiera para evitar agregar la palabra clave struct, y aún usar MyStructTag cuando un typedef no funcione (es decir, declaración de reenvío)
Editar:
Se corrigió la suposición incorrecta acerca de la declaración de estructura C99, como lo señaló con razón Jonathan Leffler .
Editar 2018-06-01:
Craig Barnes nos recuerda en su comentario que no es necesario mantener nombres separados para el nombre de la "etiqueta" de la estructura y su nombre de "typedef", como lo hice anteriormente para mayor claridad.
De hecho, el código anterior bien podría escribirse como:
IIRC, esto es realmente lo que hace C ++ con su declaración de estructura más simple, detrás de escena, para mantenerlo compatible con C:
Volviendo a C, he visto ambos usos (nombres separados y los mismos nombres), y ninguno tiene inconvenientes que yo sepa, por lo que usar el mismo nombre hace que la lectura sea más simple si no usa "espacios de nombres" separados de C para estructuras y otros símbolos .
fuente
struct
etiqueta y eltypedef
nombre. C usa un espacio de nombres diferente para lasstruct
etiquetas, por lo que puede usarMyStruct
para ambos.Para una definición de estructura que se va a utilizar en más de un archivo fuente, definitivamente debería ponerla en un archivo de encabezado. Luego, incluya ese archivo de encabezado en cualquier archivo de origen que necesite la estructura.
La
extern
declaración no se usa para definiciones de estructura, sino que se usa para declaraciones de variable (es decir, algún valor de datos con un tipo de estructura que haya definido). Si desea utilizar la misma variable en más de un archivo fuente, declare comoextern
en un archivo de encabezado como:Luego, en un archivo fuente, defina la variable real:
Si olvida hacer esto o lo define accidentalmente en dos archivos fuente, el vinculador le informará sobre esto.
fuente
GLOBAL
comoextern
o nada en la parte superior del encabezado y luego declarar las variables comoGLOBAL struct a myAValue;
. De la mayoría de los archivos de origen, los arreglos para la#define GLOBAL extern
versión que se utiliza ( declarar las variables) y desde exactamente un archivo de origen que hace que definen el vacío para ser utilizado por lo que se las variables definidas .ah:
Listo, ahora solo necesita incluir ah en los archivos donde desea usar esta estructura.
fuente