Je comprends grosement les règles avec ce que #include le prétraiteur en ce moment j'ai #include "bouger.h" à bord.h et #include "board.h" en mouvement.h. Lorsque je compile cependant, GCC se retourne et me donne une longue (ce qui ressemble à l'infini récursif) message d'erreur se retournant entre Move.h et Board.h. P>
Comment incluez-moi ces fichiers pour que je ne puisse pas y inclure de manière indéfinie? p>
7 Réponses :
Vous devez examiner Voici un exemple: P> Move. h p> board.h p> main.c p> struct board *b = malloc(sizeof(struct board));
b->m_move.m_board = b; /* make the move's board point
* to the board it's associated with */
Cela ressemble à une très bonne solution, malheureusement, je ne pouvais pas le faire fonctionner (j'ai besoin de regarder #Ifndef et de la façon dont cela fonctionne plus pour bien comprendre cela). Merci pour la réponse cependant.
Quand vous dites "N'a pas travaillé", que voulez-vous dire? En outre, vos types de déménagement et de carte se réfèrent-ils mutuellement ou sont les types utilisés dans les deux fichiers d'en-tête mais pas nécessairement dans les définitions de la structure? (Bouchon sans scrupule: voir aussi ma réponse pour certains pointeurs.)
Oui, veuillez préciser la façon dont il "n'a pas fonctionné", ce code (moins la fonction principale) devrait fonctionner à peu près.
Ni mon déménagement ni mon conseil ne sont composés l'un des autres, j'ai juste besoin du type défini pour certaines méthodes qui prennent une carte et un déménagement. Quand je dis "ça n'a pas fonctionné", cela m'a donné une erreur étrange sur quelque chose de méthodes précédemment définies ailleurs. J'ai essayé quelques modifications sur ce que vous avez proposé, mais je ne pouvais pas obtenir d'entre eux de travailler. Ne pas être une traînée, mais je suis content de la solution que j'ai maintenant pour avoir les TypeDefs dans un fichier d'en-tête séparé (Greg d'Ised).
Vous devez en avoir un d'abord. Faire une caisse avancée dans l'une d'entre elles et que celui-ci pour par exemple pourrait faire partie du fichier. P> et p> typedef struct {â¦} board;
Vous ne pouvez pas tester si une structure existe à l'aide du pré-processeur. Si vous impliquez, il devrait également faire une macro nommée, vous devriez aussi préciser.
Vous ne pouvez pas tester les typdefs avec le pré-processeur non plus ... vous auriez besoin d'ajouter littéralement quelque chose comme #define carte code> quelque part.
HMM .. L'ancien compilateur C Microsoft l'a permis de le permettre, que ce soit, je me demande si je pouvais même trouver une référence à cela. Eh bien, peu importe - beaucoup d'autres ont donné de bonnes réponses.
Comme: de cette façon board.h code> peut être compilé sans dépendance sur move.h code> et vous pouvez inclure < code> board.h code> à partir de move.h code> pour créer son contenu disponible là-bas. p> p>
Inclure les gardes feront partie de la solution à ce problème.
Exemple de Wikipedia: P>
#ifndef GRANDFATHER_H
#define GRANDFATHER_H
struct bar;
struct foo {
int member;
};
#endif
de K & R Le langage de programmation C (p 91 "Inclusion conditionnelle" dans ma copie), avec quelques modifications pour vous: et le même pour bouger.h p> < P> De cette manière, une fois qu'un en-tête a été inclus une fois, il ne sera plus inclus, car le nom 'board_h' a déjà été défini pour le pré-processeur. P> P>
Les macros commençant par un double soulignement sont réservés, vous ne devriez pas les utiliser. De plus, un soulignement suivi d'une lettre majuscule est également réservé.
@Évan - corrigé ce qui précède, merci pour le commentaire. Je pensais que mon commentaire d'édition apparaîtrait ci-dessus mais apparemment pas!
Tout d'abord, vous semblez manquer Inclure les gardes dans votre Deuxièmement, vous pouvez faire une déclaration en avant. Dans in Notez que si vous devez déclarer Donc, si vous devez utiliser les types dans les fichiers, vous devrez séparer les définitions de type: disposez de fichiers d'en-tête qui définissent Bien sûr, Vous ne pouvez pas avoir .h CODE> Fichiers, vous y incluez donc de manière récursive. C'est mauvais. move.h code>: p> board.h code>: p> struct Move Move code> et Carte de structure code> Objets (plutôt que sur le pointeur sur l'un d'entre eux) dans les fichiers, cette méthode ne sera pas travail. En effet, l'un des types est un type EM> EM> au moment de l'analyse de l'un des fichiers ( struct déplacer code> dans l'exemple ci-dessus). P> struct bouge code> et carte de structure code>, et rien d'autre (quelque chose comme mon exemple ci-dessus), puis utilisez un autre fichier d'en-tête qui fait référence à la fois struct déplacer code> et carte de structure code>. p> struct déplacer code> contenir un tableau struct code> et carte de structure code> contient un struct déplacer code> en même temps -C'est une récursion infinie et les tailles des structures seront également infinies! P> p>
Les dépendances circulaires sont une douleur dans le cul et devraient être éliminées partout où elles sont réalisables. En plus des suggestions de déclaration à terme indiquées jusqu'à présent (les alokes sont le meilleur exemple), j'aimerais lancer une autre suggestion dans les travaux: rompre la dépendance mutuelle entre la carte et le déplacement en introduisant un troisième type (appelez-le de la barre d'appelage de l'illustration; Je suis sûr que vous pouvez trouver un nom moins sucky):
struct BoardMoveAssoc {
Move m[NUM_MOVES] // or Move *m;
Board b;
};
Notez que dans un monde idéal, vous évitez les dépendances circulaires comme celle-ci. Ce n'est certainement pas toujours possible et parfois, ils peuvent être très utiles, mais chaque fois que vous créez une dépendance circulaire, vous devriez prendre un moment pour y penser et justifier son existence à vous-même.
@Greg D - Je vous ai pris conseil et j'ai créé un autre fichier appelé type.h où je fais tout mon # définir et typée. J'inclus que dans les deux dossiers, et tout est bon!