Comment déclarer une structure dans un en-tête qui est à être utilisé par de multiples fichiers en c?
Si j'ai une source.c fichier avec une structure (struct):
struct a {
int i;
struct b {
int j;
}
};
Comment cette structure peut être utilisée dans un autre fichier (c'est à dire func.c
)?
Dois-je créer un nouveau fichier d'en-tête, déclarer la structure et incluez cet en-tête dans func.c
?
Ou dois-je définir l'ensemble de la structure dans un fichier d'en-tête et de l'inclure dans les deux source.c
et func.c
? Comment peut-struct être déclaré extern
dans les deux fichiers?
Dois-je typedef
il? Si oui, comment?
- Notez que la définition de la structure n'est pas valide C. Au minimum, il devrait être un point-virgule après l'accolade fermante pour
struct b
, mais alors votre structurea
déclare un type qui n'est pas utilisé (vous devriez vous définissez un nom de membre, peut-êtrek
, après l'intérieure accolade fermante et avant le point-virgule.
Vous devez vous connecter pour publier un commentaire.
si cette structure est utilisée par un autre fichier func.c comment le faire?
Quand un type est utilisé dans un fichier (c'est à dire la touche func.fichier c), il doit être visible. La pire façon de le faire est de copier coller dans chaque fichier source, il faut.
La bonne façon est de mettre dans un fichier d'en-tête, et d'inclure ce fichier d'en-tête à chaque fois que nécessaire.
doit nous ouvrir un nouveau fichier d'en-tête et de déclarer la structure de là et de l'inclure l'en-tête de la touche func.c?
C'est la solution que j'aime de plus en plus, car elle rend le code hautement modulaire. Je voudrais le code de votre structure comme:
Je mettrais des fonctions à l'aide de cette structure dans le même en-tête (la fonction qui sont "sémantiquement" une partie de son "interface").
Et généralement, je pourrais le nom du fichier après le nom de la structure, et de l'utiliser de nouveau de nom pour choisir l'en-tête des gardes définit.
Si vous avez besoin de déclarer une fonction à l'aide d'un pointeur vers une struct, vous n'aurez pas besoin de toute la structure de la définition. Une simple déclaration anticipée comme:
Sera suffisant, et il diminue le couplage.
ou peut-on définir la structure globale dans le fichier d'en-tête et de l'inclure à la fois la source.c et la touche func.c?
C'est une autre façon, un peu plus facile, mais moins modulaire: un peu de code qu'il suffit d'utiliser votre structure reste encore du travail pour inclure tous les types.
En C++, cela pourrait donner lieu à d'intéressants complication, mais c'est hors sujet (pas de C++ tag), donc je ne m'étendrai pas.
alors comment déclarer cette structure en extern dans les deux fichiers. ?
Je n'arrive pas à voir le point, peut-être, mais Greg Hewgill a une très bonne réponse à son post Comment déclarer une structure dans un en-tête qui est à être utilisé par de multiples fichiers en c?.
nous typedef il, alors comment?
La raison étant que C struct la gestion peut être une douleur: Vous devez déclarer le mot-clé struct partout où il est utilisé:
Tout un typedef va vous permettre de vous l'écrire sans le mot-clé struct.
Il est important vous gardez toujours un nom pour la structure. Écrit:
va juste créer un anonyme struct avec une définition de type-ed nom, et vous ne serez pas en mesure de le déclarer. Afin de garder le format suivant:
Ainsi, vous serez en mesure d'utiliser MyStruct partout où vous voulez éviter d'ajouter le mot-clé struct, et toujours utiliser MyStructTag lorsqu'un typedef ne fonctionne pas (c'est à dire avant la déclaration)
Edit:
Corrigé hypothèse erronée sur C99 struct déclaration, comme l'a fait remarquer à juste titre par Jonathan Leffler.
Modifier 2018-06-01:
Craig Barnes nous rappelle dans son commentaire que vous n'avez pas besoin de garder des noms différents pour la struct "tag" nom et sa "typedef" nom", comme je l'ai fait ci-dessus pour des raisons de clarté.
En effet, le code ci-dessus pourrait bien être écrite comme suit:
Autant que je me souvienne, c'est en fait ce que le C++ ne avec sa plus simple struct déclaration, en coulisses, pour garder compatible avec C:
En C, j'ai vu les deux usages (séparez les noms et les mêmes noms), et aucun n'a les inconvénients que je connais, donc, en utilisant le même nom rend la lecture plus simple si vous n'utilisez pas C séparé "espaces de noms" pour les structures et autres symboles.
struct
tag et letypedef
nom. C utilise un espace de noms différent pourstruct
balises, de sorte que vous pouvez utiliserMyStruct
pour les deux.Pour une définition de la structure qui doit être utilisée dans plus d'un fichier source, vous devriez certainement mettre dans un fichier d'en-tête. Ensuite inclure ce fichier d'en-tête de n'importe quel fichier source les besoins de la structure.
La
extern
déclaration n'est pas utilisé pour la structure des définitions, mais est plutôt utilisé pour les déclarations de variables (qui est, certaines données de la valeur avec un type de structure que vous avez défini). Si vous souhaitez utiliser la même variable dans plus d'un fichier source, le déclarer commeextern
dans un fichier d'en-tête comme:Puis, dans un fichier source, définissez la variable réelle:
Si vous oubliez de le faire ou accidentellement le définir en deux fichiers source, l'éditeur de liens vous permettra de savoir à ce sujet.
GLOBAL
commeextern
ou rien en haut de l'en-tête et ensuite déclarer des variables commeGLOBAL struct a myAValue;
. À partir de la plupart des fichiers source, vous arrangez pour le#define GLOBAL extern
la version utilisée (déclarant les variables) et à partir d'un fichier source, il provoque le vide à définir à être utilisé si les variables sont défini.un.h:
là vous allez, maintenant vous avez juste besoin d'inclure un.h pour les fichiers où vous voulez utiliser cette structure.