IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Erreur Pointeur sur fonction dans une structure


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Erreur Pointeur sur fonction dans une structure
    Bonjour, j'ai un problème j'ai une erreur lors de la déclaration d'une structure ayant comme "variable" des pointeur sur fonction ! Je précise que toute les fonction sur lequel pointe les pointeur on les même arguments.
    J'ai peur que l'erreur viennent du fait que un des paramètre est un tableau de la structure même car il me semble que la déclaration de mes pointeurs est juste

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef struct Perso{
        int hp;
        int pm;
        int mana;
        void (*ptr1)(Perso*,char**,char);
        void (*ptr2)(Perso*,char**,char);
        void (*ptr3)(Perso*,char**,char);
    }Perso;
    ERREUR: error: unknown type name 'Perso' pour les 3 pointeurs

    Merci et bonne soirée

  2. #2
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 559
    Points
    1 559
    Par défaut
    Hello,

    Ligne ?? -- on va dire 5 à 7 (utilise # pour poster du code): Perso*struct Perso *.

    Perso ne sera connu par le compilateur qu'après la dernière ligne que tu montres....
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2019
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Hi,

    Pour une meilleure lisibilité et une meilleure compréhension de ton propre code, je t'encourage à mettre des noms différents entre ta structure et ton typedef.
    Par exemple, ta structure pourrais etre "s_perso" (pour structure perso) et ton typedef pourrait être t_perso (pour typedef perso).
    Ainsi, ton erreur d'appeler perso au lieu de struct perso est plus visible et tu gagne en lisibilité de ton code.

    Enjoy !

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonjour Chiron_kheiron oui cela serait effectivement plus claire merci de ta réponse !

    Bonjour edgarjacobs oui cela me paraît évident maintenant que dans ma structure le typedef a pas encore "agi" , du coup je l'ai mis avant et magie ça marche

    Merci pour vos réponses et bonne journée

  5. #5
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    C'est l'occasion de rappeler à quoi sert typedef.

    • Mais d'abord à quoi il ne sert pas : éviter d'écrire struct par fainéantise.


    En effet, dans 99% des cas en C, quand on définit des fonctions sur un type struct, on doit être conscient que ce sont des machins qui ont des champs (membres), et que c'est une structure, pas une union. Si c'est pour mettre s_ devant pour s'en rappeler, c'est pas très malin, autant mettre le vrai truc.

    • Un bon usage, en effet c'est quand il y a abstraction. On n'a pas (pas trop) besoin de savoir ce que c'est. Juste que ça se manipule à travers un pointeur. Un exemple, FILE.
    • Un autre usage, c'est quand un type relativement compliqué revient souvent. Exemple


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void (*ptr1)(Perso*,char**,char);
    void (*ptr2)(Perso*,char**,char);
    void (*ptr3)(Perso*,char**,char);
    Chacun ses goûts, mais 3 fois le même, ça me paraîtrait plus clair sous la forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Action ptr1, ptr2, ptr3;
    pour ça il suffit d'un typedef bien considéré

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef void (*Action)(struct Perso *, char **, char);
    Et là on tombe dans une circularité : Action qui est défini à partir de struct Perso qui est défini à partir d'Action.

    Pour s'en sortir,
    • on commence par déclarer l'existence d'un type struct Perso
    • puis on définit Action
    • et enfin on définit struct Perso


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct Perso;   // déclaration : le type "struct Perso" existe.
     
    // on construit Action
    typedef void (*Action)(struct Perso *, char **, char);
     
    // maintenant on peut _définir_ struct Perso
    struct Perso{
        int hp;
        int pm;
        int mana;
        Action ptr1, ptr2, ptr3;
    };

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Je ne partage pas cet avis sur "typedef struct". Quand tu fais Point p;, tu te doutes bien que ce n'est pas un type de base, que donc c'est une structure, que donc elle a des champs. Faire struct Point p; n'aide pas fondamentalement à savoir, quelques lignes plus loin, si p.x = 1; est l'accès à un membre d'une structure ou d'une union. Les unions sont tellement rares comparées aux structures, je pense qu'il vaut mieux faire un "traitement" spécial pour les unions et se simplifier la vie pour les structures.

    Je plussoie totalement pour l'utilisation du typedef pour Action ! Le code est carrément plus léger !

  7. #7
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    - Erreurs de logique détectées dans : tu te doutes bien que ce n'est pas un type de base donc c'est une struct

    • C'est pas que je me doute. Je sais. Les types de base, ils sont peu nombreux et parfaitement connus
    • et il n'y a pas que les struct dans la vie, il y a aussi les unions et les enums. Et puis ça pourrait être un pointeur. ou un tableau. Vu le nombre de gens qui nous font typedef struct Element *Liste; c'est pas une vue de l'esprit....


    Pour des trucs évidents comme Point, qui ont une signification évidente par rapport au problème, ça va, mais sinon ça fait des embrouilles, d'où la recommandation de certains, genre notation hongroise, de préfixer par s_. Mais là ça n'apporte rien, sinon que s_point c'est plus court que struct point, La belle affaire...

    Et ils feraient la même chose avec #define s_point struct point



    - Les unions rares ?

    J'ai quelques souvenirs d'en avoir vu (et manipulé) plein dans la Xlib, en particulier les événements

    https://www.x.org/releases/X11R7.6/d...ml#Event_Types

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef union _XEvent {
         int                            type;          /* must not be changed */
         XAnyEvent                      xany;
         XKeyEvent                      xkey;
        ... 
    } Xevent;
    et les exemples qui utilisaient XEvent plutôt que union _XEvent, ça aidait vraiment pas.

    Par ailleurs, si on part sur la base de fonctions qui ne font pas 3 kilomètres de long, quand une variable est déclarée explicitement struct Point, ça aide forcément davantage à être conscient que c'est une structure, quelques lignes plus loin.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 984
    Points
    30 984
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par ekieki Voir le message
    Vu le nombre de gens qui nous font typedef struct Element *Liste; c'est pas une vue de l'esprit....
    Pas vraiment d'accord. Je pars bien évidemment du principe que l'on discute entre "habitués" à la fois du C et de ses bonnes pratiques. Et les bonnes pratiques veulent que l'on ne masque jamais un pointeur derrière un nom de type. Et donc même si tu as déjà vu ça dans des trucs de débutants, tu ne peux pas utiliser cet exemple pour assoir tes propos parce que théoriquement tu ne le verras jamais dans des trucs de gens habitués.

    Citation Envoyé par ekieki Voir le message
    Pour des trucs évidents comme Point, qui ont une signification évidente par rapport au problème, ça va, mais sinon ça fait des embrouilles, d'où la recommandation de certains, genre notation hongroise, de préfixer par s_. Mais là ça n'apporte rien, sinon que s_point c'est plus court que struct point, La belle affaire...
    Euh non, ce n'est pas "pour faire plus court" (d'autant plus que si c'est le nom d'une structure, alors ce sera struct s_point et non s_point). On préfixe les structures par "s_" et les types par "t_" déjà pour les reconnaitre facilement dans les déclarations. Et aussi pour pouvoir laisser le nom de base libre pour les variables. Parce que si j'ai un type "Point", et que je veux une variable pour stocker mon point, ben je peux pas l'appeler "Point" cette variable. Je suis obligé de trouver un autre nom et rien que ça ça m'énerve (et je vais pas l'appeler "point" !!!). Ensuite bon je trouve par exemple que je vais l'appeler "coordonnee" ben je me trouve alors à définir un Point coordonnee et là ça m'énerve encore parce que instinctivement je ne distingue plus ce qui est "type" de ce qui est "variable".
    Alors que si j'ai un "struct s_point" alors je peux écrire struct s_point point. Et si j'ai fait l'effort de faire au début un typedef struct s_point { ... } t_point alors je peux écrire t_point point et là je suis super heureux. Surtout que si je n'ai pas besoin d'une structure récursive, alors le vocable "s_point" devient inutile et je peux raccourcir ça en typedef struct { ... } t_point.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre régulier Avatar de ekieki
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Avril 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Enseignant Chercheur

    Informations forums :
    Inscription : Avril 2014
    Messages : 34
    Points : 103
    Points
    103
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Bonjour

    Pas vraiment d'accord. Je pars bien évidemment du principe que l'on discute entre "habitués" à la fois du C et de ses bonnes pratiques. .
    C'est un principe.

    Tu peux partir d'où tu veux, mais la réalité où on est, c'est que celui qui a posé la question n'est ni habitué au C ni à ses bonnes pratiques, la preuve c'est qu'il se demandait pourquoi il avait une erreur dans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef {
      ... Machin ...
    } Machin;
    Ce que nous savons bien sûr tous. Enfin presque : faut bien apprendre.

    *
    Parce que si j'ai un type "Point", et que je veux une variable pour stocker mon point, ben je peux pas l'appeler "Point" cette variable.
    Tu peux l'appeler point. . Majuscule pour les types, minuscules pour les variables, c'est une convention courante.

    * Au passage remarque que tu peux quand même faire
    struct point point;ton argument est donc contre le typedef.
    N'est-ce pas ironique ?

    * mais de toutes façons, ce n'est pas une bonne pratique de désigner un variable par un nom qui reflète son type, genre int entier; boolean test; float nombre.

    Il est largement préférable que ça reflète son rôle. Le point il s'appellera plutôt centre, coin_haut_gauche, milieu, intersection, position....

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 04/03/2015, 08h47
  2. Réponses: 22
    Dernier message: 14/04/2014, 00h02
  3. pointeur sur tableau dans une structure
    Par rollbich dans le forum Débuter
    Réponses: 3
    Dernier message: 02/06/2013, 22h23
  4. Réponses: 7
    Dernier message: 04/12/2012, 19h02
  5. pointeur de fonction dans une structure
    Par Flow_75 dans le forum C++
    Réponses: 1
    Dernier message: 27/12/2008, 11h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo