La déclaration des structures en C

Résolu/Fermé
Antoine - 23 juin 2010 à 12:27
 Antoine - 23 juin 2010 à 14:33
Bonjour,

Dans le cadre d'un projet en langage C, je suis amené à définir une structure "struct commande" qui contient un pointeur qui pointe sur le nom de la commande et un pointeur vers la fonction à executer (la commande). Cette fonction prend un paramètre : un pointeur vers une structure de type "struct menu". Cette strucure, contient elle un pointeur vers une structure "struct commande", entre autres.
Le problème est que, quelque soit la structure que je déclarerai en premier, il y aura une erreur : une des structures de sera pas définie.
Mon code donne quelque chose comme cela:

Code C:
typedef struct commande
{
     char* texte; /* nom de la commande */
     void(*fonction) (menu*); /* fonction de la commande */
} commande;

typedef struct menu
{
     /* ... quelques éléments ici */
    commande* commande; /* pointeur sur la structure de commande */
} menu;


Mes questions sont:
- Est-il possible de concevoir un tel code?
- Si oui, déclarer la structure "struct menu" en même temps que les paramètres de la fonction commande permeterait-il de résoudre le problème? Cependant je crois que le C89 ne l'autorise pas (à vérifier).

3 réponses

Rctll Messages postés 499 Date d'inscription dimanche 11 mai 2008 Statut Membre Dernière intervention 30 juin 2010 1 409
23 juin 2010 à 12:40
Mon cours de C est relativement loin, mais je croit qu'en faisant une declaration partielle avant ça marche :
typedef struct menu;
typedef struct commande
{
     char* texte; /* nom de la commande */
     void(*fonction) (menu*); /* fonction de la commande */
} commande;

typedef struct menu
{
     /* ... quelques éléments ici */
    commande* commande; /* pointeur sur la structure de commande */
} menu;

2
Merci,
Je ne connaissait pas cette astuce : "typedef struct menu;".
J'ai testé le code, bien que tout m'ait l'air correct, il ne semble malheureusement pas fonctionner correctement chez moi. (GCC ne me rapporte pas d'erreur dans la déclaration de la structure "commande", mais curieusement, il m'indique une erreur lors de l'utilisation du type "commande" dans la structure "struct menu")
En revanche j'ai trouvé une solution décrite ci dessous qui semble fonctionner.
0
Toutes mes excuses, ton code fonctionne très bien. (je l'avais mal recopié).
Merci, c'est bien plus lisible que ma proposition.
0
Rctll Messages postés 499 Date d'inscription dimanche 11 mai 2008 Statut Membre Dernière intervention 30 juin 2010 1 409
23 juin 2010 à 14:16
content d'avoir pu t'aider !
0
Bonjour,

Pour moi une syntaxe correcte ressemblerait plutôt à

/* Déclaration courte + typedef */
typedef struct menu menu;  /* Ne pas oublier le nom du typedef */

typedef struct commande
{
     char* texte; /* nom de la commande */
     void(*fonction) (menu*); /* fonction de la commande */
} commande;

typedef struct menu
{
     /* ... quelques éléments ici */
    commande* commande; /* pointeur sur la structure de commande */
} menu;


ou à


/* Déclaration courte */
struct menu; /* Ne pas faire un typedef inutile. */

typedef struct commande
{
     char* texte; /* nom de la commande */
     void(*fonction) (struct menu*); /* fonction de la commande */
} commande;

typedef struct menu
{
     /* ... quelques éléments ici */
    commande* commande; /* pointeur sur la structure de commande */
} menu;


(avec une préférence pour la deuxième)
2
Merci, le second code fonctionne aussi très bien.
Pour ce qui est du premier, je pense que c'est le code de Rctll qui est valide. En effet dans le premier code, il y a un typedef de trop pour la structure "menu".
Après, la différence entre les deux codes est juste la position du typedef.
En tous cas, les deux sont beaucoup mieux que ma première proposition, ne serait-ce que pour la lisibilité.
0
Il semblerait que j'ai trouvé (plus rapidement que ce que je croyais).
Un code "équivalent" autorisé serai:

Code C:
typedef struct menu
{
     /* ... quelques éléments ici */
     struct commande
     {
          char* texte;
          void (*fonction)(struct menu*);
     } *commande;
} menu;
typedef struct commande commande;


Le code semble fonctionner. Si quelqu'un pouvait apporter confirmation...
Ici, j'ai déclarer la structure "struct commande" à l'intérieur de la structure "struct menu". Toutefois, je ne sais toujours pas si l'inverse est possible. (Déclarer une structure dans un paramètre).

Voilà, si ça peut aider quelqu'un...
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
23 juin 2010 à 12:58
Salut,
je comprends pas pourquoi tu veux passer ta structure menu en parametre....
typedef struct menu
{
/* ... quelques éléments ici */
char* texte;
void (*fonction)(char*);
} menu;
normalement cela suffirait.....non?
@+
0
Ce code n'est pas équivalent au premier. En effet si on passe un pointeur sur un char en paramètre, il est impossible pour la fonction d'acceder aux élément de la structure "menu". Par exemple, dans la fonction:
Code C:
void fonction_quelconque(menu* menu)   
{   
     /* "menu->commande.texte" serait inaccessible à moins de connaitre la taille exacte de tous les élements de la structure et de les atteindre en ajoutant des constantes au pointeur "menu", ce qui est très fortement déconseillé! */   
}   
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
23 juin 2010 à 13:31
Salut,
pourquoi tu veux avoir acces à menu->commande.texte dans ta fonction...puisque tu le passes en parametre....
tu l'as en tant que parametre...non?
0
chuka Messages postés 965 Date d'inscription samedi 11 octobre 2008 Statut Membre Dernière intervention 29 juillet 2010 378
23 juin 2010 à 14:23
Je comprends toujours pas la philosophie de ton code...c'est pas grave..mais il me semble que ce que tu veux faire ressemble à cela.....
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef void (*ptrfonc)(char* ph);
typedef struct ptTx{
    char* commande;
    ptrfonc fonction;
}ptTx;
void affiche(char* ph);
int main()
{
    char*hello="Hello World";
    ptTx*ptx=(ptTx*)malloc(sizeof(ptTx));
    ptx->fonction=affiche;
    ptx->commande=hello;
    ptrfonc f=(ptrfonc)ptx->fonction;
    (*f)(ptx->commande);
    getchar();
    free(ptx);
    return 0;
}

void affiche(char* ph)
{
    printf("%s",ph);
}


@+
0
La structure "menu" passée en paramètre n'est pas necessairement la même que celle qui contient la structure "commande".
Je parvient ainsi à gérer des sous-menus avec la même fonction.
Mais à la rigueur, ce n'est pas important.
0