si cette structure doit être utilisée par un autre fichier func.c, comment faire ?
Lorsqu'un type est utilisé dans un fichier (par exemple le fichier func.c), il doit être visible. La pire façon de le faire est de le copier-coller dans chaque fichier source qui en a besoin.
Le bon moyen est de le mettre dans un fichier d'en-tête, et d'inclure ce fichier d'en-tête chaque fois que cela est nécessaire.
devons-nous ouvrir un nouveau fichier d'en-tête, y déclarer la structure et inclure cet en-tête dans le fichier func.c ?
C'est la solution que je préfère, car elle rend le code très modulaire. Je coderais votre struct comme :
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
Je mettrais les fonctions utilisant cette structure dans le même en-tête (la fonction qui fait "sémantiquement" partie de son "interface").
Et généralement, je pouvais nommer le fichier après le nom de la structure, et utiliser à nouveau ce nom pour choisir les gardes d'en-tête définis.
Si vous devez déclarer une fonction en utilisant un pointeur vers la structure, vous n'aurez pas besoin de la définition complète de la structure. Une simple déclaration en avant comme :
struct a ;
Sera suffisant, et il diminue l'accouplement.
ou pouvons-nous définir la structure totale dans le fichier d'en-tête et l'inclure à la fois dans source.c et func.c ?
C'est un autre moyen, plus facile en quelque sorte, mais moins modulaire : Un code n'ayant besoin que de votre structure pour fonctionner devrait quand même inclure tous les types.
En C++, cela pourrait conduire à une complication intéressante, mais c'est hors sujet (pas de balise C++), donc je ne m'étendrai pas.
alors comment déclarer cette structure comme externe dans les deux fichiers. ?
Je ne vois pas l'intérêt, peut-être, mais Greg Hewgill a une très bonne réponse dans son article. http://stackoverflow.com/questions/228684/how-to-declare-a-structure-in-a-header-that-is-to-be-used-by-multiple-files-in-c#228691 .
Comment le définir alors ?
- Si vous utilisez C++, ne le faites pas.
- Si vous utilisez le C, vous devriez.
La raison en est que la gestion des structures C peut être pénible : Vous devez déclarer le mot-clé struct partout où il est utilisé :
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
Alors qu'un typedef vous permettra de l'écrire sans le mot clé struct.
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
Il est important vous gardez toujours un nom pour la structure. L'écriture :
typedef struct
{
/* etc. */
} MyStruct ;
créera simplement une structure anonyme avec un nom typé, et vous ne serez pas en mesure de la déclarer à nouveau. Respectez donc le format suivant :
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
Ainsi, vous pourrez utiliser MyStruct partout où vous voulez éviter d'ajouter le mot-clé struct, et toujours utiliser MyStructTag lorsqu'un typedef ne fonctionnera pas (c'est-à-dire une déclaration en avant).
Edit :
Correction d'une hypothèse erronée concernant la déclaration C99 struct, comme l'a remarqué Jonathan Leffler.