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 :

Trier un tableau de pointeurs sur des éléments de type quelconque


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut Trier un tableau de pointeurs sur des éléments de type quelconque
    Bonjour à tous,

    Comme le titre l'indique je dois trier un tableau de pointeurs vers des éléments de type quelconques, la fonction de tri reçoit en argument un pointeur vers une fonction qui compare deux éléments et renvoi -1,0 ou 1 suivant le résultat de la comparaison.

    Hélas, je ne trouve même pas l'entête de ma fonction.
    Exemple, si je trie des doubles, il me suffit de mettre :

    void tri (double tab[], etc...)

    Mais sans connaître le type des éléments du tableau, comment puis je faire ???

    Merci d'avance pour votre aide

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    Salut moi je verrais un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void sort(void **tab, char (*cmp_element)(const void *elt_1, const void *elt_2));
    void **tab car c'est un tableau de pointeur,
    (*cmp_element) c'est le pointeur sur fonction qui a pour prototype (const void *elt_1, const void *elt_2)

    A la bonne synthaxe pres ca doit etre qq chose comme ca...lol

    Je sais pas si ca peut eclairer ton esprit....????


    Je pense que l'idee est de mettre dans le prototype des void * pour ensuite les caster..... non??? dites le moi si je me trompe que je ne raconte pas trops de betise...

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut
    Oula, dur de comprendre ce que tu m'as mis lol mais je vais essayer...

    pourquoi met tu char devant le (*cmp_element) ??
    Je ne comprends pas non plus le const devant elt1 et elt2

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    J'ai mis le char car la fonction de comparaison te retourne -1, 0, 1 donc ca tient dans un octet donc je propose d'utiliser un char qui est suffisant!!

    Les const dans le prototype ca permet juste de t'assurer que tu ne va pas modifier les arguments que tu passes... c'est pour constant!!


    Est-ce un chouilla plus clair????
    Est-ce que tu sais manipuler les pointeurs de fonctions..???

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    pour essayer d'illustrer voici un petit exemple pour les unsigned char

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char cmp_unsigned_char(const void *elt_1, const void *elt_2)
    {
        unsigned char *a, *b;
     
        a = (unsigned char *) elt_1;   /*cast*/
        b = (unsigned char *) elt_2;
     
    ..../*apres c'est facile de comparer 2 unsigned char*/
    }
    pour utiliser cette fonction tu feras qq chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void **tab;
     
    /* allocation et initialisation de tab */
    sort(tab, &cmp_unsigned_char)

    et maintenant est ce un peu plus clair???

    Par contre je n'ai pas teste avec un compilo donc je le fais de memoire desole d'avance si il y a qq coquille!!

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut
    D'accord je vois mieux,

    Je cherche sur internet des tuto pour les pointeurs de fonctions mais hélas je ne trouve pas grand chose qui m'éclaircit.

    Je fais un test simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int tri_quest2 (void **tab,int (*cmp_element)(void const *e1, void const *e2)) {
      return cmp_element(tab[0],tab[1]);;
    }
    SI je veux tester ma fonction avec strcmp, et deux chaines de caractères comment dois je appeler ma fonction ?
    J'ai essayé ça mais sans réussite...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int main() {
      char* tab;
      tab = (int) malloc (sizeof(int)*2);
      tab[0] = "test";
      tab[1] = "test1";
      printf("%s %s %d \n", tab[0], tab[1],  tri_quest2 (tab,strcmp());
    }

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut
    Ha je n'avais pas vu ta dernière réponse, je lis....

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par allezlolo Voir le message
    Comme le titre l'indique je dois trier un tableau de pointeurs vers des éléments de type quelconques, la fonction de tri reçoit en argument un pointeur vers une fonction qui compare deux éléments et renvoi -1,0 ou 1 suivant le résultat de la comparaison.
    Quelconque mais de même type, OK ? Sinon, il est absurde de vouloir trier autre chose qu'un tableau.
    Mais sans connaître le type des éléments du tableau, comment puis je faire ???
    Tu ne peux pas.

    Explique ton problème réel, tu as sans doute une erreur de conception.

    EDIT : Si j'ai bien compris, tu veux créer une fonction de tri générique ? Ca existe déjà en C standard : qsort().

    Tu veux créer ton propre qsort(), c'est ça ?

    C'est une technique assez avancée...

    Il faut commencer par définir correctement l'interface. Les paramètres sont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void * tab : adresse du premier élément du tableau à trier
    size_t nb_elem : nombre d'éléments du tableau
    size_t sz_elem : taille en bytes d'un élément du tableau
    int (*fp_compare)(void const *a, void const *b) : adresse de la fonction de comparaison
    Celle-ci est forcément externe, car il faut pourvoir comparer les éléments pour pouvoir trier.

    Elle a donc la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int compare (void const *a, void const *b)
    Les 2 paramètres sont a et b, les adresses respectives des 2 élément en train d'être comparés.

    Pour faire la comparaison, on a besoin de connaitre le type (qui doit être le même pour les deux):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    T const *pa = a;
    T const *pb = b;
    ensuite, on compare de qui doit l'être... et on retour,e <0, 0 ou >0 selon le résutat. Par exemple :
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       return strcmp (pa, pb);
    etc.

    Tu as un algo de tri qui fonctionne ?

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Quelconque mais de même type, OK ? Sinon, il est absurde de vouloir trier autre chose qu'un tableau.

    Tu ne peux pas.

    Explique ton problème réel, tu as sans doute une erreur de conception.
    Oui les éléments du tableau sont de même type et je passe en argument un pointeur vers une fonction qui compare deux éléments.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut
    Merci pour ces précisions

    Oui j'ai un algorithme pour le trie qui fonctionne.

    Mon problème est surtout d'arriver à utiliser correctement ma fonction de comparaison dans ma fonction principale.

    Comme je l'ai expliquer dans le message plus haut, je cherche tout simplement pour commencer à réussir à compiler et renvoyer quelque chose de correct avec ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int tri_quest2 (void **tab,int (*cmp_element)(void const *e1, void const *e2)) {
      return cmp_element(tab[0],tab[1]);;
    }
     
    int main() {
      char** tab;
      tab =  malloc (sizeof(char*)*2);
      tab[0] = "test";
      tab[1] = "test1";
     
      tri_quest2(tab, &strcmp); 
    }
    Je ne vois pas ce qui bloque sur ce petit bout de code...?

    EDIT : oui je cherche à implenté une sorte de qshort sans utiliser forcément le tri rapide.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    En regardant de plus pres ton erreur de compilation je me suis apercu que le prototype de strcmp est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int strcmp(const char *s1, const char *s2);
    or dans ta fonction de tri veut une fonction qui a comme prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int cmp_element(void const *e1, void const *e2)
    le probleme vient de la je pense

    fait toi une fonction de comparaison ca se fait en 10 lignes et en 2 min si t'as pas trop l'habitude... test la une fois que t'es sure quelle fonctionne attaque toi a la faire passer un argument dune fonction.....

    etape par etape... ;-)

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    okay on a poster en meme temps donc desole si jai dit des choses inutile...lol

    mais strcmp veut des char et toi tu veu une fonction de comparaison qui prend des void.... la c'est un probleme...

    donc utilise pas strcmp() ou pas directement

    mais fait le d'abord avec des char ou un type tres simple a comparer, puis fait ta fonction de comparaison en qq ligne (qui prends des void) et je ne vois pas pkoi ca ne marchera pas.....

    par acqui de conscience j'ai regarde des vieux sources et cété comme ca ke j'ai utiliser les pointeurs de fonction....

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 79
    Par défaut
    Merci à tous pour vos réponses,
    Je me replonge bien dedans, je fais les quelques fonctions pour tester et je vous tiens au courant si tout marche.

    En tout cas, merci pour tout

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 859
    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 859
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par barbsbou Voir le message
    mais strcmp veut des char


    Citation Envoyé par allezlolo Voir le message
    C'est bon ça marche

    Il me fallait en fait mettre

    if (cmp_element(tab[i],tab[j])==1)

    ça me parait un peu bizarre car je croyais que 1 était équivalent à true...

    Enfin bon ça marche c'est le principal
    Hum...
    Les fonctions de comparaison utilisées pour qsort ont pour règle de renvoyer 0 quand les éléments sont égaux, -1 ou 1 quand les éléments sont inégaux (le signe +- servant à montrer lequel est plus petit que lequel)
    Si chez-toi ça marche avec une fonction qui renvoie 1 en cas d'égalité, alors
    - soit ton algo n'est pas normalisé (j'ai pas tout regardé)
    - soit ça ne marche que par hasard

    Sinon, pour répondre à ton interrogation, 1 est effectivement équivalent à true...
    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]

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

Discussions similaires

  1. xsd:all sur des éléments de type différents
    Par Steph0 dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 12/08/2012, 18h04
  2. Réponses: 3
    Dernier message: 15/03/2007, 12h09
  3. Tableau de pointeurs sur objets
    Par bassim dans le forum C++
    Réponses: 11
    Dernier message: 13/12/2005, 19h45
  4. Problème de *pointeur sur des char
    Par Spartan03 dans le forum C++
    Réponses: 2
    Dernier message: 18/09/2005, 14h20
  5. vector de pointeurs sur des objet
    Par jean-bobby dans le forum SL & STL
    Réponses: 26
    Dernier message: 06/08/2004, 14h54

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