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 :

Pointeur générique (void *)


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut Pointeur générique (void *)
    Bonjour,

    Soit le code ci-dessous :
    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
    31
    32
    33
    #include <stdio.h>
     
    void *essai1(void *p)
    {
      void **q = (void **)p;
      return (*q);
    }
     
    void *essai2(void *p)
    {
      double **q = (double **)p;
      return (*q);
    }
     
    int main(void)
    {
      {/* 1er exemple */
        int x = 4;
        int *a = &x;
     
        printf("a=%p\n", (void *)a);
        printf("*p=%p\n", essai1(&a));
        printf("*p=%p\n\n", essai2(&a));
      }
      {/* 2eme exemple */
        char *a = "abCd";
     
        printf("a=%p\n", a);
        printf("*p=%p\n", essai1(&a));
        printf("*p=%p\n\n", essai2(&a));
      }
      return 0;
    }
    [Dans essai2, j'ai mis le type double comme j'aurais pu mettre n'importe quel autre type.] Pour chaque exemple, les adresses qui s'affichent sont identiques. Ma question est : les fonctions essai1 et essai2 ou tout autre fonction similaire me renverront-elles toujours a, quel que le type de l'objet vers lequel a pointe ?

    Merci,

    Candide

  2. #2
    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 c-candide
    Ma question est : les fonctions essai1 et essai2 ou tout autre fonction similaire me renverront-elles toujours a, quel que le type de l'objet vers lequel a pointe ?
    Oui. Ton code est inutilement compliqué et il manque des choses ...
    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
    31
    32
    33
    34
    35
     
    #include <stdio.h>
     
    void *essai1 (void *p)
    {
       void **q = p;
       return *q;
    }
     
    void *essai2 (void *p)
    {
       double **q = p;
       return *q;
    }
     
    int main (void)
    {
       {                            /* 1er exemple */
          int x = 4;
          int *a = &x;
     
          printf ("a=%p\n", (void *) a);
          printf ("*p=%p\n", essai1 (&a));
          printf ("*p=%p\n\n", essai2 (&a));
       }
     
       {                            /* 2eme exemple */
          char const *a = "abCd";
     
          printf ("a=%p\n", (void *) a);
          printf ("*p=%p\n", essai1 (&a));
          printf ("*p=%p\n\n", essai2 (&a));
       }
       return 0;
    }

  3. #3
    Membre averti
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Par défaut
    les notions utiliées ds votre code:
    -->Pointeur de Pointeur
    -->Conversion de type de pointeur( void * => double * ,...):
    ---->Explicite et implicite

    mais vs remarquez que vs tombez sur la meme valeur adressée.
    une remarque pr cette conversion implicite il est possible :
    ...
    int *a = &x;
    ....
    char *a = "abCd";
    ...

    vous pouvez essayer ce code ca donne le meme chose alors porqoui le pointeur en double (Ptr de Ptr :: **)
    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
    31
    32
    33
    34
    35
     
    #include <stdio.h>
     
    void *essai1(void *p)
    {
      void *q = p;
      return (q);
    }
     
    void *essai2(void *p)
    {
      double *q = (double *)p;
      return (q);
    }
     
    int main(void)
    {
      {/* 1er exemple */
        int x = 4;
        int *a = &x;
     
        printf("a=%p\n", (void *)a);
        printf("*p=%p\n", essai1(&a));
        printf("*p=%p\n\n", essai2(&a));
      }
      {/* 2eme exemple */
        char *a = "abCd";
     
        printf("a=%p\n", a);
        printf("*p=%p\n", essai1(&a));
        printf("*p=%p\n\n", essai2(&a));
      }
       getchar();
      return 0;
    }

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut Encore une petite question svp
    Bonsoir Emmanuel et merci de ta réponse.

    Citation Envoyé par Emmanuel Delahaye
    Oui. Ton code est inutilement compliqué et il manque des choses ...
    Ah ! rien ne t'échappe ! En effet, j'avais crû que l'abscence du cast en void ** et double ** m'envoyait un warning.
    Pour les parenthèses inutiles après le return, OK. Je suppose que le manque auquel tu fais allusion est le const mais je ne vois pas en quoi c'est obligatoire, c'est des habitudes de bonne programmation, non ? ou j'ai manqué quelque chose d'important ?

    Sinon, encore une petite confirmation si possible. Je me lance dans l'écriture de programmes génériques et tout n'est pas encore bien clair. Par exemple, je dispose d'un tableau de pointeurs vers des "données" (de type et de taille inconnus a priori) et je passe ce tableau en argument à une fonction ayant en paramètre un pointeur sur void. Dans cette fonction, j'ai besoin de récupérer l'adresse des données (que je fais passer ensuite à une fonction-callback). D'où mon interrogation toute bête dans le programme tout bête suivant :
    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
    #include <stdio.h>
     
    void *essai(void *p)
    {
      char **char_p = p;
      return *(char_p + 1);
     }
     
    int main(void)
    {
      int a = 2007, b= 22;
      int *t[2];
     
      t[0] = &a;
      t[1] = &b;  
     
      printf("adresse de b = %p \n", (void *)t[1]);
      printf("adresse retournee %p\n", essai(t)); 
     
      return 0;
    }
    C'est bien normal et portable que les mêmes adresses s'affichent, n'est-ce pas ? J'utilise le type char dans ma fonction essai mais n'importe quel type donnerait la même réponse, est-ce bien ainsi ?

    Merci encore,

    Candide

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Ben d'abord ta fonction est void * ...

    Il faudrait caster en void * ton retour..

    D'autre part ton arithmétique de pointeur (+1) ne marche qu'avec des char..

    Et enfin, pour faire ce genre de routine générique, ou tu maniupleras un tableau, moi je passerais plutot l'adresse d'une structure qui contient le tableau... Mais je n'ai peut être pas tous les atouts en main..

  6. #6
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par c-candide
    Je suppose que le manque auquel tu fais allusion est le const mais je ne vois pas en quoi c'est obligatoire, c'est des habitudes de bonne programmation, non ? ou j'ai manqué quelque chose d'important ?
    Une constante chaîne de caractère n'étant pas modifiable, il est normal de pointer dessus avec une variable de type pointeur sur char constant. gcc avec l'option -Wwrite-strings donne un avertissement lorsque le qualificatif const n'est pas utilisé.

    Citation Envoyé par c-candide
    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
    #include <stdio.h>
     
    void *essai(void *p)
    {
      char **char_p = p;
      return *(char_p + 1);
     }
     
    int main(void)
    {
      int a = 2007, b= 22;
      int *t[2];
     
      t[0] = &a;
      t[1] = &b;  
     
      printf("adresse de b = %p \n", (void *)t[1]);
      printf("adresse retournee %p\n", essai(t)); 
     
      return 0;
    }
    C'est bien normal et portable que les mêmes adresses s'affichent, n'est-ce pas ? J'utilise le type char dans ma fonction essai mais n'importe quel type donnerait la même réponse, est-ce bien ainsi ?
    C'est normal que la même adresse s'affiche dans les deux cas. Maintenant, je ne vois pas pourquoi tu déclares char_p comme une variable de type char **. t[1] est de type pointeur sur int et est équivalent à *(t + 1). Et *(char_p + 1) et char_p[1] sont équivalents. Comme char_p est initialisé avec la valeur de t et que tous deux pointent sur un pointeur, (t + 1) ou (char_p + 1) référencent la même adresse. Attention tout de même: se jouer du système de typage peut réserver des surprises...

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut
    Citation Envoyé par mujigka
    Une constante chaîne de caractère n'étant pas modifiable, il est normal de pointer dessus avec une variable de type pointeur sur char constant. gcc avec l'option -Wwrite-strings donne un avertissement lorsque le qualificatif const n'est pas utilisé.
    Normal, ça veut dire quoi ? En tous cas, ça n'a rien d'obligatoire, si j'ai bien compris on utilise const essentiellement pour des raisons de sécurité et de commentaire du code. En particulier dans un mini-exemple, il me paraît excessif de dire que "ça manque".

    C'est normal que la même adresse s'affiche dans les deux cas.
    Merci de cette confirmation.

    Maintenant, je ne vois pas pourquoi tu déclares char_p
    comme une variable de type char **
    tu veux dire "comme une variable de type char **" plutôt "comme une variable de type machin **" ? Pas de raison particulière et c'est justement le sens de la deuxième quastion que je posais.


    Attention tout de même: se jouer du système de typage peut réserver des surprises...
    Oui, j'ai entendu dire que ça pouvait être dangereux, les casts peuvent être dangereux puisqu'ils font taire le compilateur mais tout ceci reste assez vague pour moi, si quelqu'un pouvait développer ou mieux, donner un court exemple.

    Mais il me semble que dans certaines circonstances, on ne peut se passer de "se jouer du système de typage", en particulier quand on écrit du code générique, non ?

    Candide

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par c-candide
    Normal, ça veut dire quoi ? En tous cas, ça n'a rien d'obligatoire, si j'ai bien compris on utilise const essentiellement pour des raisons de sécurité et de commentaire du code. En particulier dans un mini-exemple, il me paraît excessif de dire que "ça manque".
    Normal n'est pas le terme approprié, j'aurais du mettre naturel. Maintenant, tu as raison, la norme du langage ne l'impose pas. C'est toutefois une bonne habitude à prendre, même dans un mini-exemple. Comme je le perçoit, c'était juste un conseil qui t'a été donné, et non un reproche...

    Citation Envoyé par c-candide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Maintenant, je ne vois pas pourquoi tu déclares char_p 
    comme une variable de type char **
    tu veux dire "comme une variable de type char **" plutôt "comme une variable de type machin **" ?
    Via ta fonction essai(), c'est à quelques détails prêts, c'est comme si tu écrivais.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int a = 2007;
    int b= 22;
    int *t[2] = {&a, &b};
    char **char_p = (void *) t;
    Au final, comme tu l'as fait remarquer, *char_p et *t contiennent la même adresse. t s'attend à trouver un entier de type int à cette adresse, tandis que char_p s'attend à trouver un caractère.

    Citation Envoyé par c-candide
    Mais il me semble que dans certaines circonstances, on ne peut se passer de "se jouer du système de typage", en particulier quand on écrit du code générique, non ?
    Oui, je n'ai pas dit le contraire, mais c'est délicat, et il faut savoir ce qui l'on fait (et c'est pas toujours très propre). Pour tout savoir au sujet de la programmation générique en C, un excellent tutoriel est celui de Romuald Perrot http://rperrot.developpez.com/articles/c/genericite/ .

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Pour ce qui est du type de char_p, tu aurais pu déclarer char_p en void** ou même en intptr_t*, tu devrais avoir le même résultat.
    Le fait de le déclarer en char** donne lieu à plus de confusion d'ailleurs, car on pense que la taille devient importante alors qu'elle ne l'est pas.
    Je recommande le type void**.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    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 c-candide
    Je suppose que le manque auquel tu fais allusion est le const mais je ne vois pas en quoi c'est obligatoire, c'est des habitudes de bonne programmation, non ? ou j'ai manqué quelque chose d'important ?
    Oui. Il n'est pas garanti qu'une chaine soit modifiable. Il est donc conseillé de le préciser avec const. Une option de gcc permet de le vérifier.

    http://emmanuel-delahaye.developpez....tm#cfg_compilo
    Sinon, encore une petite confirmation si possible. Je me lance dans l'écriture de programmes génériques et tout n'est pas encore bien clair. Par exemple, je dispose d'un tableau de pointeurs vers des "données" (de type et de taille inconnus a priori) et je passe ce tableau en argument à une fonction ayant en paramètre un pointeur sur void.
    Si c'est un tableau générique, il va manquer des informations. Regarde le prototype de qsort() et tu vas comprendre.

  11. #11
    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 c-candide
    C'est bien normal et portable que les mêmes adresses s'affichent, n'est-ce pas ? J'utilise le type char dans ma fonction essai mais n'importe quel type donnerait la même réponse, est-ce bien ainsi ?
    Oui. La taille des pointeurs est la même quelque soit le type.

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut
    Citation Envoyé par mujigka
    Pour tout savoir au sujet de la programmation générique en C, un excellent tutoriel est celui de Romuald Perrot http://rperrot.developpez.com/articles/c/genericite/ .
    OK merci de la référence.

  13. #13
    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 souviron34
    Ben d'abord ta fonction est void * ...

    Il faudrait caster en void * ton retour..
    Ben non, pas la peine. Le type void * est compatible avec tous les type pointeurs sur objet. La conversion est implicite.
    D'autre part ton arithmétique de pointeur (+1) ne marche qu'avec des char..
    Elle fonctionne avec tout les pointeurs typés. Ici, on a un pointeur sur char* (char **), le fonction est parfaitement défini et conforme.

  14. #14
    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 Médinoc
    Pour ce qui est du type de char_p, tu aurais pu déclarer char_p en void** ou même en intptr_t*, tu devrais avoir le même résultat.
    Le fait de le déclarer en char** donne lieu à plus de confusion d'ailleurs, car on pense que la taille devient importante alors qu'elle ne l'est pas.
    Je recommande le type void**.
    +1

  15. #15
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut
    Citation Envoyé par Médinoc
    Le fait de le déclarer en char** donne lieu à plus de confusion d'ailleurs, car on pense que la taille devient importante alors qu'elle ne l'est pas.
    Je recommande le type void**.
    Merci de cette réponse qui me permet d'y voir plus clair. Je crois d'ailleurs que c'est la technique utilisée dans la fonction swap générique du tutorial recommandé par mujigka. En plus, je vois qu'Emmanuel confirme.

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 80
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Si c'est un tableau générique, il va manquer des informations. Regarde le prototype de qsort() et tu vas comprendre.
    Tu veux dire la taille unitaire des éléments ou leur nombre ? Bien sûr. Avant de me lancer dans de la programmation générique, j'ai étudié en détail l'implémentation de qsort ou de bsearch par Plauger et je pense avoir compris comment ça fonctionne. Mais pour ce que je veux faire, il me semble que j'ai besoin d'un niveau de déréférencement de plus (d'où mes questions avec des void ** ou machin **). Je m'explique :

    Je veux faire un module de traitement de tableaux génériques et qui incorpore des opérations génériques entre tableaux.

    Par exemple, le module doit être capable de faire des sommes de tableaux au sens évident du terme, par exemple la somme du tableau d'entiers {2, 5} et du tableau {6, 1} va donner le tableau {8, 6}.

    Mais je veux que cette addition soit très générique parce que je voudrais qu'elle marche non seulement pour des entiers mais pour des doubles, des types que j'aurais définis comme un type fraction (au sens usuel du terme) avec une définition de préférence générique d'une addition de fractions. Et je me suis rendu compte que les arguments de ma fonction de somme générique devaient être non par les données (ci-dessus, les données étaient des int ou encore les fractions) mais des pointeurs vers les données tout simplement parce que la fonction de somme générique de tableaux ne peut pas savoir de quelle quantité de mémoire le résultat de la somme va nécessiter, seule une fonction ad hoc travaillant directement avec les données peut donner cette quantité de mémoire. La taille du résultat peut donc être quelconque, par exemple imaginons qu'on définisse l'addition de deux chaînes comme leur concaténation (ie "bla" plus "blabla" donne "blablabla"). Je peux alors définir la somme de deux tableaux de chaînes de manière naturelle, par exemple,
    {"azert", "bla"} plus {"y", "blabla"} serait {"azerty", "blablabla"} donc il va falloir allouer pour le résultat, ce n'est pas ma fonction de somme générique de tableaux qui pourra le faire mais ma fonction de concaténation. Voilà, je ne sais pas si je suis parvenu à expliquer clairement mon problème. Je suis intéressé par tout avis.

    Merci

    Candide

  17. #17
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    si ça vous intéresse, j'ai un petit module qui lit un fichier de ressources comme on en trouve dans X/Motif :

    fichier de ressources :

    des lignes de texte contenant des chaînes, des caractères, des entiers, des réels, des booléens,

    module :

    lit le fichier
    stocke chaque élément dans une structure avec le bon type..

    Mais aussi

    assigne une valeur par défaut à chaque élément de la structure..

    Exemple de fonction (juste le début) :

    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
     
    static int Init_Resource ( char *param_type, 
    	                      void *address, void *value )
    {
    char   **caddress = (char **)address, *cvalue = (char *)value ;
    int     *iaddress = (int *)address, *ivalue = (int *)value ;
    float   *faddress = (float *)address, *fvalue = (float *)value ;
    double  *daddress = (double *)address, *dvalue = (double *)value ;
    Boolean *baddress = (Boolean *)address, *bvalue = (Boolean *)value ;
     
       if ( strcmp ( param_type, "char" ) == 0 )
         {
         }
       else
         {
         }
    }
    Exemple d'appel :

    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
     
       if ( MCore_DefineResourceElement ( "MCore", "appliDocument", "char",
    				      &(Config->appli_document), "" ) == ERROR )
          return ERROR;
     
       i = 0; /* will get detected from dbName using /etc/services */
       if ( MCore_DefineResourceElement ( "MCore", "dbPort", "int", 
    				      &(Config->port), &i ) == ERROR )
     
       f = 6378137.0 ;
       if ( MCore_DefineResourceElement ( "MCore", "datum_SemiMajorAxis", "double",
    				      &(Config->datum_semi_majoraxis), &f ) == ERROR )
          return ERROR;
     
     
       F = False ;
       if ( MCore_DefineResourceElement ( "MCore", "allowBadColorBehaviour", "Boolean", 
    				      &(Config->allow_bad_color_behaviour), &F ) == ERROR )
          return ERROR;

  18. #18
    Membre averti
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Par défaut
    Je pense que j'ai compri ce que vs voulez faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    TabEntier            = {545,54654,88,...}
    TabDecimale        = {0.54,...}
    TabCaractere       = {'h','k',...}
    TabTypeCompose = {??}
    TabAutreType      = {??}
    c possible de faire des operations arithemtiques sur ces tableaux avec la programmation generique mais une chose que vous savez C++ et un langauage à typage statique , par exemple : TabEntier[0] + TabCaractere[0] = le resultat serai de quele type ??
    En Java j'ai vu des exemples avec des Objets generiques vous pouvez le faire egalement En C++ egalement vs pouvez utilisez les Templates peut etre qi'il ya des structures prédefinies ds la Standard Template Library (STL).

    Solution (POO sans Templates) si j'ai compri votre probleme je vs propose :
    1.Creer une classe mere qui contient les element de base du taritement
    2.Creer des classes filles pr chaque type de Tableau
    3.Tester les types des opérandes avant d'executer l'operation
    4.S'il sagit d'une conversion implicite faite par le compilateur ca marche si non vous exigez la conversion explicitement
    5.S'il y a lieu d'une conversion la classe fille s'en charge ex: ClassTabEntier pour manipuler les entiers si non la classe mere fait l'affaire.
    J'espere que ca marche !!

  19. #19
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par rebassou
    Je pense que j'ai compri ce que vs voulez faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    TabEntier            = {545,54654,88,...}
    TabDecimale        = {0.54,...}
    TabCaractere       = {'h','k',...}
    TabTypeCompose = {??}
    TabAutreType      = {??}
    c possible de faire des operations arithemtiques sur ces tableaux avec la programmation generique mais une chose que vous savez C++ et un langauage à typage statique , par exemple : TabEntier[0] + TabCaractere[0] = le resultat serai de quele type ??
    En Java j'ai vu des exemples avec des Objets generiques vous pouvez le faire egalement En C++ egalement vs pouvez utilisez les Templates peut etre qi'il ya des structures prédefinies ds la Standard Template Library (STL).

    Solution (POO sans Templates) si j'ai compri votre probleme je vs propose :
    1.Creer une classe mere qui contient les element de base du taritement
    2.Creer des classes filles pr chaque type de Tableau
    3.Tester les types des opérandes avant d'executer l'operation
    4.S'il sagit d'une conversion implicite faite par le compilateur ca marche si non vous exigez la conversion explicitement
    5.S'il y a lieu d'une conversion la classe fille s'en charge ex: ClassTabEntier pour manipuler les entiers si non la classe mere fait l'affaire.
    J'espere que ca marche !!
    Sauf qu'on est sur le forum dédié au langage C. Il est possible de mettre en place un modèle objet en C supportant les relations d'héritage, le polymorphisme, etc., mais ce n'est pas trivial.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  20. #20
    Membre averti
    Inscrit en
    Février 2007
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 14
    Par défaut
    Citation Envoyé par mujigka
    ... Il est possible de mettre en place un modèle objet en C supportant les relations d'héritage, le polymorphisme, etc., mais ce n'est pas trivial.

    Thierry
    je n'ai pas bien compri ,j'aimerai que vous pouvez l'expliquer un peu !
    merci d'avance.

Discussions similaires

  1. portabilité du pointeur générique void*
    Par uknow dans le forum C
    Réponses: 6
    Dernier message: 09/01/2011, 15h48
  2. Pointeur générique vers d'autres types d'objets
    Par LapinGarou dans le forum MFC
    Réponses: 11
    Dernier message: 15/09/2006, 16h48
  3. déréférencer un pointeur générique ?
    Par tintin72 dans le forum C
    Réponses: 6
    Dernier message: 23/07/2006, 12h40
  4. Question sur les pointeurs génériques
    Par mikedavem dans le forum C
    Réponses: 16
    Dernier message: 24/05/2006, 11h56
  5. pointeur générique
    Par ghostdog dans le forum C
    Réponses: 14
    Dernier message: 09/11/2005, 15h23

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