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 :

error: dereferencing pointer to incomplete type


Sujet :

C

  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut error: dereferencing pointer to incomplete type
    Je bute sur cette erreur depuis des heures et je ne comprends pas d'où elle peut bien venir...

    Voici la fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    File transfertGRDversFile(GRD a,File f)
    {
    	if(!estVideGRD(a))
    	{
    		transfertGRDversFile(a->gauche,f);
    		enfiler(&f,f.debut,a->val);
    		transfertGRDversFile(a->droite,f);
    	}
    	return f;
    }
    error: dereferencing pointer to incomplete type
    J'obtiens cette erreur sur chaque paramètre partant de mon arbre. a->gauche a->droite a->val


    Je tiens à préciser que la fonction enfiler avait bien été testé et elle fonctionne correctement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int enfiler (File * suite, Element * courant, int donnee);
    Ici ce que je veux faire c'est envoyer dans une file les entiers de mon arbre.


    Au paravant, j'avais une fonction de type void qui affichait un arbre sur le même principe et qui fonctionnait comme il faut, j'ai donc simplement repris la même structure en remplaçant l'affichage par le fait d'enfiler l'entier dans ma file que je retourne à la fin.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void triGRD(GRD a)
    {
    	if(!estVideGRD(a))
    	{
    		triGRD(a->gauche);
    		printf("%d\n",a->val);
    		triGRD(a->droite);
    	}
    }

    J ne vois vraiment pas d'où provient l'erreur ni à quoi elle est du

    Need help

    Cdlt, Merci.


    EDIT: Je rajoute les structures on sait jamais =)

    Arbre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef struct unfeuille {
    	int val;
    	struct unfeuille *gauche;
    	struct unfeuille *droite;
    }feuille;
     
    typedef struct unfeuille * GRD;
    File
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    typedef struct ElementListe{
      int donnee;
      struct ElementListe *suivant;
    } Element;
     
    typedef struct ListeRepere{
      Element *debut;
      Element *fin;
      int taille;
    } File;

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Bonjour,

    Cacher un pointeur dans un typedef (lors de la définition de GRD) est une mauvaise pratique, même si elle se fait beaucoup à l'école.
    À part cela, quel compilateur utilises-tu ? Ça fonctionne avec une version récente de GCC.

    « error: dereferencing pointer to incomplete type » signifie que tu essaies d'accéder aux membres d'un type qui n'a pas encore été totalement défini. C'est utile par exemple lorsque l'on veut définir deux structures distinctes A et B qui se référencent mutuellement (avec un pointeur). Comme il faut bien déclarer l'une avant l'autre, on déclare les noms de structures avec « struct A; struct B; » mais sans définir le contenu de ces structures. Ça nous permet ensuite de les définir pleinement avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct A
    {
        B * pointeur_vers_b;
        …
    };
     
    struct B
    {
        A * pointeur_vers_a;
        …
    };
    Il se peut que tu aies oublié d'inclure les headers définissant pleinement ces structures en tête du code source dans lequel se produit l'erreur.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    J'utilise Gcc avec la plupart des options possible; on avait créer un alias en tp et j'ai jamais supprimé. Je trouve que c'ets mieux comme ça, ça force à plus de rigueur.

    Dans le fichier où la dite fonction est présente, j'utilise les en-tête suivante


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include "file_statique.h"
    #include "arbre.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
     
    la fonction
     
     
    le main
    file_statique.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #ifndef ___FILLE_STATIQUE___
    #define ___FILLE_STATIQUE___
     
    /* FirstInFirstOut */
    #define file_donnee(suite) suite->debut->donnee
     
    typedef struct ElementListe{
      int donnee;
      struct ElementListe *suivant;
    } Element;
     
    typedef struct ListeRepere{
      Element *debut;
      Element *fin;
      int taille;
    } File;
     
    /* initialisation */
    void initialisation (File * suite);
     
    /* ENFILER*/
    int enfiler (File * suite, Element * courant, int donnee);
     
    /* DE_FILER*/
    int de_filer (File * suite);
     
    /* Affiche la file */
    void affiche(File *suite);
     
    #endif

    Et dans arbre.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct unfeuille * GRD;
    arbre.c

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct unfeuille {
    	int val;
    	struct unfeuille *gauche;
    	struct unfeuille *droite;
    }feuille;


    En fait la structure de base de GRD est "caché" dans le .c auquel le main n'a pas accès; et donc c'est la source de l'erreur ? Donc je prend cette erreur à cause de ma protection de structure sur l'arbre ?

    C'est un peu con...

    Il n'y aurait pas moyen "d'inclure" le .c pour que ça passe au compilo ?

  4. #4
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    C'était bien vu, en envoyant la structure d'arbre.c dans arbre.h ça a marché.

    Mais du coup maintenant j'ai une autre question

    Si j'avais voulu garder ma protection de structure est ce que je n'aurais pas pu m'en sortir quand même ?

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par Amnael Voir le message
    En fait la structure de base de GRD est "caché" dans le .c auquel le main n'a pas accès; et donc c'est la source de l'erreur ? Donc je prend cette erreur à cause de ma protection de structure sur l'arbre ?
    Oui.

    C'est un peu con... Il n'y aurait pas moyen "d'inclure" le .c pour que ça passe au compilo ?
    En fait, ici, ton erreur n'est pas technique mais conceptuelle : tu souhaites que GRD soit un type opaque MAIS tu veux quand même accéder à ses membres depuis ton programme principal ! Si ceux-ci sont publics, alors leur déclaration doit l'être aussi. Dans le cas contraire, il faut utiliser des accesseurs.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par Amnael Voir le message
    Si j'avais voulu garder ma protection de structure est ce que je n'aurais pas pu m'en sortir quand même ?
    Nos derniers commentaires se sont croisés.

    Comme dit dans le précédent, donc, c'est à toi d'être au clair sur ce que tu veux réellement faire à la base, le reste devrait venir naturellement derrière. Si tu veux entièrement protéger ton type, tu peux commencer par placer sa déclaration dans un fichier *.h distinct, qui ne sera inclus que par les routines de gestion de ton objet. Ensuite, il faudra que tu mettes à disposition du public un ensemble de facilités pour exploiter ton objet, sinon il ne servira à rien.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Amnael Voir le message
    Il n'y aurait pas moyen "d'inclure" le .c pour que ça passe au compilo ?
    Bonjour
    On n'inclut jamais un .c dans un .h (de même qu'on n'écrit pas de code dans un .h) pour plusieurs raisons
    • le .h est destiné au public (qui aura ainsi le prototype des fonctions utilisées) tandis que le code peut être secret/protégé. Mettre ton code dans un vecteur public empêche cette protection
    • si le .h est inclut dans différents sources du projet, ton code dupliqué peut alors provoquer une collision lors de la compil
    • de toute façon vu qu'il est toujours possible de ne pas le faire ; ca montre une erreur de conception


    Et sinon comme cela a été dit, on ne masque jamais un pointeur dans un typedef. C'est une habitude qu'adoptent les profs de C pour essayer de "laisser de coté" les pointeurs et éviter de les expliquer (les comprennent-ils eux-mêmes parfois on se le demande) mais malheureusement pour eux (et pour leurs élèves), le pointeur est un élément incontournable du C. Or le masquer a tendance à le faire oublier alors qu'il est primordial de toujours connaitre les pointeurs qu'on manipule pour justement bien les manipuler...
    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]

  8. #8
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    Merci pour vos réponses à tous les deux, c'est un peu plus clair désormais; même si je ne pense pas avoir la totalité du bagage à disposition encore =)


    Lorsque vous dites
    Et sinon comme cela a été dit, on ne masque jamais un pointeur dans un typedef

    Vous parlez par exemple de la ligne ou je fais un typedef struct unfeuille* GRD ?


    C'est vrai que dans tous les tuto que je lis, je ne vois jamais ce type de redéfinition; et au lieu d'avoir GRD on aurait eu unfeuille**


    Si c'est bien de cela que vous parler, je trouve ça aussi plus logique de ne pas faire ça, mais dans les cours ça fait aussi parti de la notation; au final je dirais que ça donne un sens plus clair au code pour quelqun qui le relirait derrière nous.

    Je pense que c’est pas mauvais du moment qu'on est conscient que c'est un pointeur qui se cache derrière.

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Amnael Voir le message
    C'est vrai que dans tous les tuto que je lis, je ne vois jamais ce type de redéfinition; et au lieu d'avoir GRD on aurait eu unfeuille**
    Exact. Etant donné que la feuille d'un arbre est un pointeur, modifier ce pointeur dans une fonction implique que la fonction reçoive l'adresse de cette feuille, autrement dit un "feuille **"

    C'est pour éviter ce cas qu'il est courant de définir aussi une structure pour l'arbre lui-même

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct s_feuille {
    	int val;
    	struct s_feuille *gauche;
    	struct s_feuille *droite;
    }t_feuille;
     
    typedef struct {
    	t_feuille *racine;
    } t_arbre;

    Ainsi, une fonction recevant comme paramètre l'adresse de cet arbre (un t_arbre *arbre) pourra sans souci accéder et modifier la racine (arbre->racine=...). Bref on rajoute un élément intermédiaire entre les deux étoiles de ce ** qui t'embête.
    Ce qui ouvre aussi d'autres possibilités. Comme par exemple rajouter des infos sur l'arbre lui-même comme par exemple sa profondeur maximale, le nb de ses éléments, etc. Ainsi toute fonction recevant cet arbre aura immédiatement accès à tous ces paramètres. Bref c'est un premier pas vers le "tout objet"...

    Accessoirement tu remarqueras que nommer ses structures "s_xxx" et ses types "t_xxx" renforce aussi la lisibilité du code tout en gardant le token "arbre" disponible pour un nom de variable.

    Citation Envoyé par Amnael Voir le message
    Je pense que c’est pas mauvais du moment qu'on est conscient que c'est un pointeur qui se cache derrière.
    Tu comprendras quand tu reviendras sur un de tes codes six mois après...
    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]

  10. #10
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par Amnael Voir le message
    Merci pour vos réponses à tous les deux, c'est un peu plus clair désormais; même si je ne pense pas avoir la totalité du bagage à disposition encore =)
    Même sans bagage, tu peux quand même te pencher sur ceci :
    • Tu veux que ton type soit opaque ;
    • Ton programme appelle quand même a->gauche, a->droite et a->val.


    En principe, tu n'es même pas censé savoir qu'il existe des membres qui s'appellent « gauche », « droite » et « val ». Tu ne le sais que parce que c'est toi qui a écrit l'objet. :-)

    Vous parlez par exemple de la ligne ou je fais un typedef struct unfeuille* GRD ?
    Oui.

    Si c'est bien de cela que vous parler, je trouve ça aussi plus logique de ne pas faire ça, mais dans les cours ça fait aussi parti de la notation; au final je dirais que ça donne un sens plus clair au code pour quelqun qui le relirait derrière nous.
    Il y a beaucoup de professeurs qui font cela parce qu'il est très fréquent, en école d'informatique, d'apprendre d'emblée les rudiments du C et ceux de l'algorithmique. Ça a l'air d'être une manière simple de dissocier les deux mais en réalité, on se fait tout de suite rattraper par les contraintes que l'on a voulu contourner. Ne serait-ce que parce qu'il faut quand même utiliser les bonnes conventions d'appel (par exemple, « -> »).

  11. #11
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    Tant que j'y suis j'ai un autre soucis que je qualifierais également de conceptuel dans cet algo avec cette fonction


    Admettons que je passe en paramètre un arbre ayant 3 valeurs 4 5 2

    A chaque fois je fais un appel récursif; donc ma file va se compléter au fur et à mesure

    f1 : 4
    f2: 4 - 5
    f3: 4 - 5 - 2

    Mais il va y avoir un soucis au niveau du retour en fait; car étant récursif lorsque l'appel se termine

    ma file ne contient plus 4 - 5 - 2 mais bel et bien seulement 4 car la première fonction sera la seule retourné !!!

    J'ai essayé diverses choses pour régler ce soucis; mais je ne vois pas comment faire !

    Une idée ?

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Amnael Voir le message
    Une idée ?
    J'ai pas trop lu ton code en fait. Mais d'après ce que tu décris ici, il semble que tu remplisses une liste chainée avec les valeurs de l'arbre.

    Donc si c'est ça, il ne faut pas que ta fonction récursive "retourne" quelque chose mais "remplisse" simplement ta liste (qui est un élément extérieur à la fonction donc accessible par toutes les instances de celle-ci)

    Typiquement, un truc de ce genre

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    fonction(t_feuille *f, t_liste *liste)
    {
        ajouter(liste, feuille->val);
        if (f->gauche)
            fonction(f->gauche, liste);
        if (f->droite)
            fonction(f->droite, liste);
    }

    Au retour final, ta liste sera complètement remplie. Et la fonction "ajouter()" sera plus facile à programmer si, à l'instar de mon exemple précédent, tu crées une structure dédiée à la liste elle-même...

    Toutefois tu peux quand-même retourner qqchose mais alors c'est qqchose indiquant si tout se passe bien ou pas. Et dans ce cas, il faut penser que si qqchose se passe mal dans un sous-appel, il faut veiller à remonter l'info à l'appelant initial

    Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fonction(t_feuille *f, t_liste *liste)
    {
        if (ajouter(liste, feuille->val) == NULL) return NULL;
        if (f->gauche)
            if (fonction(f->gauche, liste) == NULL) return NULL;
        if (f->droite)
            if (fonction(f->droite, liste) == NULL) return NULL;
     
        return f;      // On renvoie ce qu'on veut tant que c'est pas NULL
    }
    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]

  13. #13
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    J'ai pas trop lu ton code en fait. Mais d'après ce que tu décris ici, il semble que tu remplisses une liste chainée avec les valeurs de l'arbre.
    Oui c'est ça.

    Donc si c'est ça, il ne faut pas que ta fonction récursive "retourne" quelque chose mais "remplisse" simplement ta liste (qui est un élément extérieur à la fonction donc accessible par toutes les instances de celle-ci)
    C'est pas le passage de paramètre qui plante; la fonction tourne bien et la liste est modifié

    En fait ça fait

    récursif 1: L....1
    récursif 2: L....1.....2
    récursif 3: L....1.....2.....3

    Je suis obligé de passer par un appel récursif pour obtenir la file complète 1 2 3

    Mais le problème est que lorsque les appels récursif se termine


    récursif 3: L....1.....2.....3
    récursif 2: L....1.....2
    récursif 1: L....1

    Et du coup on retourne L...1 à la fin; ce que moi je voudrais faire en fait c'est pour ainsi dire court circuiter les appels récurcif sous jacent pour retourner la file L 1 2 3 et pas la L 1


    Au retour final, ta liste sera complètement remplie.
    Elle l'est aussi avec un code, mais à un instant donné seulement.

  14. #14
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Citation Envoyé par Amnael Voir le message
    En fait ça fait
    Je suis obligé de passer par un appel récursif pour obtenir la file complète 1 2 3
    Mais le problème est que lorsque les appels récursif se termine
    Et du coup on retourne L...1 à la fin; ce que moi je voudrais faire en fait c'est pour ainsi dire court circuiter les appels récurcif sous jacent pour retourner la file L 1 2 3 et pas la L 1
    On a bien compris, mais c'est ce que l'on te dit au départ : ta fonction, récursive ou non, doit intervenir sur un arbre défini à l'extérieur. Elle n'est pas censée travailler sur ses propres arbres locaux.

    Donc, tu fais ton premier appel en passant en argument un arbre existant. Cette fonction peut éventuellement se rappeler elle-même (récursivement, donc) en passant le même paramètre, ou éventuellement un pointeur vers un autre endroit de l'arbre. Le fait de quitter la fonction ne va pas « déconstruire » ce qu'elle vient de remplir. Elle aura simplement apporté sa pierre à un édifice.

  15. #15
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2011
    Messages
    756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 756
    Par défaut
    Je comprends surement de travers mais il me semble bien que l'arbre n'est pas en local de la fonction, il est bien passé en paramètre; d'ailleurs je ne cherche pas à le modifier je ne fais que transférer ou copier ses valeurs.

  16. #16
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 801
    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 801
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Amnael Voir le message
    Je comprends surement de travers mais il me semble bien que l'arbre n'est pas en local de la fonction, il est bien passé en paramètre; d'ailleurs je ne cherche pas à le modifier je ne fais que transférer ou copier ses valeurs.
    Oui mais tu veux modifier la liste !!!

    Donc en passant aussi ta liste à la fonction, celle-ci peut la remplir. Et (si elle ne la vide pas en remontant), lorsque la fonction termine ses appels et revient à l'appelant originel, la liste est totalement remplie...

    Citation Envoyé par Amnael Voir le message
    récursif 1: L....1
    récursif 2: L....1.....2
    récursif 3: L....1.....2.....3

    Mais le problème est que lorsque les appels récursif se termine

    récursif 3: L....1.....2.....3
    récursif 2: L....1.....2
    récursif 1: L....1
    Non
    récursif 3: L....1.....2.....3
    récursif 2: L....1.....2.....3
    récursif 1: L....1.....2.....3

    Citation Envoyé par Amnael Voir le message
    Et du coup on retourne L...1 à la fin; ce que moi je voudrais faire en fait c'est pour ainsi dire court circuiter les appels récurcif sous jacent pour retourner la file L 1 2 3 et pas la L 1
    Ben justement, si tu regardes bien mon premier exemple, je ne retourne rien et la liste est quand-même remplie !!!

    Regarde, un simple exemple fonctionnel de démo

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <stdio.h>
    #include <string.h>
     
    void reverse(char*, char*);
    int main()
    {
    	char chaine[100];
    	char phrase[]="Il etait une fois une belle princesse...";
     
    	memset(chaine, 0, 100);
    	reverse(phrase, chaine + strlen(phrase) - 1);
    	printf("%s\n", chaine);
    }
     
    void reverse(char *phrase, char *dest)
    {
    	if (phrase[0]) reverse(phrase + 1, dest - 1);
    	dest[0]=phrase[0];
    }

    La chaine est remplie dans la fonction récursive qui remplit à chaque fois un caractère en partant de la fin et en revenant vers le début.
    Et au retour de la fonction, la chaine reste remplie...
    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]

Discussions similaires

  1. error: dereferencing pointer to incomplete type
    Par rufa11 dans le forum Réseau
    Réponses: 2
    Dernier message: 11/02/2015, 09h41
  2. dereferencing pointer to incomplete type
    Par Almenor dans le forum Débuter
    Réponses: 10
    Dernier message: 31/05/2012, 10h17
  3. dereferencing pointer to incomplete type
    Par Anasiben dans le forum Débuter
    Réponses: 3
    Dernier message: 19/05/2011, 16h39
  4. forward declaration et error: dereferencing pointer
    Par vincent.mbg dans le forum C
    Réponses: 4
    Dernier message: 15/06/2010, 12h57
  5. dereferencing pointer to incomplete type
    Par Newgaia dans le forum Débuter
    Réponses: 2
    Dernier message: 19/04/2009, 19h00

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